如何筛选关联翻译表仅含一条en locale记录的grouper数据?
问题描述
假设有一个名为grouper的表:
| id | column_a |
|---|---|
| 1 | value |
| 2 | value |
还有一个名为translation的表:
| id | locale | text | grouper_id |
|---|---|---|---|
| 1 | en | some en text | 1 |
| 2 | es | some es text | 1 |
| 3 | fr | some fr text | 1 |
| 4 | en | some en text | 2 |
grouper与translation是一对多关联关系。需要查询**仅关联一条翻译记录,且该记录的locale为'en'**的grouper(比如id为2的grouper,它只关联一条id为4的翻译记录,且locale是'en')。
尝试了以下SQL语句:
SELECT grouper.id, grouper.column_a FROM grouper INNER JOIN translation ON grouper.id = translation.grouper_id GROUP BY grouper.id HAVING COUNT(translation.id) = 1
这条语句能筛选出仅关联一条翻译记录的grouper,但没考虑locale条件。尝试添加条件时遇到两个问题:
- 若添加
WHERE translation.locale = 'en',会返回所有包含'en'翻译的grouper,不管它总共有多少条翻译记录,结果不符合要求。 - 若把条件加到HAVING子句,写成
HAVING COUNT(translation.id) = 1 AND translation.locale = 'en',MySQL会报错:
Unknown column 'translation.locale' in 'having clause'.
解决方案
要同时满足“仅关联1条翻译记录”和“这条记录locale为'en'”两个条件,可以通过以下几种方式实现:
方法一:结合聚合函数判断locale
SELECT grouper.id, grouper.column_a FROM grouper INNER JOIN translation ON grouper.id = translation.grouper_id GROUP BY grouper.id HAVING COUNT(translation.id) = 1 AND MAX(translation.locale) = 'en'
解释:因为已经通过COUNT(translation.id) = 1确保每个grouper只有一条翻译记录,用MAX()或MIN()就能拿到这条唯一记录的locale值,再判断是否等于'en'即可。
方法二:条件计数验证locale
SELECT grouper.id, grouper.column_a FROM grouper INNER JOIN translation ON grouper.id = translation.grouper_id GROUP BY grouper.id HAVING COUNT(translation.id) = 1 AND SUM(CASE WHEN translation.locale = 'en' THEN 1 ELSE 0 END) = 1
解释:SUM(CASE...)会统计该grouper中locale为'en'的记录数量,等于1就说明唯一的那条翻译记录符合要求。
方法三:子查询筛选符合条件的grouper
SELECT g.id, g.column_a FROM grouper g WHERE EXISTS ( SELECT 1 FROM translation t WHERE t.grouper_id = g.id GROUP BY t.grouper_id HAVING COUNT(*) = 1 AND MAX(t.locale) = 'en' )
解释:通过子查询先找出满足条件的grouper_id,再关联主表获取所需字段,逻辑更直观。
内容的提问来源于stack exchange,提问作者Son_of_Odin
相关产品推荐
相关产品推荐

