我有3张桌子。
table deals
+----+------+-------------+
| id | name | location_id |
+----+------+-------------+
table deals_user_actions
+---------+---------+
| deal_id | user_id |
+---------+---------+
table locations
+----+-----------+----------+
| id | longitude | latitude |
+----+-----------+----------+
我原来的工作查询是:
SELECT d.id, d.title
FROM deals d
JOIN locations l ON l.id = d.location_id
WHERE ST_Distance_Spheroid(ST_MAKEPOINT(l.longitude, l.latitude), ST_MAKEPOINT(18, 59), 'SPHEROID[\"WGS 84\",6378137,298.257223563]') < 50
但我需要选择只有一定数量用户操作的交易,例如:
SELECT
d.id,
d.title,
COUNT(dua.deal_id) AS numUserActions
FROM deals d
JOIN locations l ON l.id = d.location_id
JOIN deals_user_actions dua ON dua.deal_id = d.id
WHERE
ST_Distance_Spheroid(ST_MAKEPOINT(l.longitude, l.latitude), ST_MAKEPOINT(18, 59), 'SPHEROID[\"WGS 84\",6378137,298.257223563]') < 50
AND numUserActions == 10
但是在这里它抱怨在GROUP BY子句中没有d.id,l.longitude和l.latitude列。但是当我添加它们时,查询中只返回一个结果。
那么您如何建议更改查询以使结果以COUNTed JOINed表为条件?
答案 0 :(得分:2)
没有理由加入deals_user_actions
。只需在WHERE子句中使用子选择来计算:
SELECT d.id, d.title
FROM deals d
JOIN locations l ON l.id = d.location_id
WHERE ST_Distance_Spheroid(ST_MAKEPOINT(l.longitude, l.latitude),
ST_MAKEPOINT(18, 59),
'SPHEROID[\"WGS 84\",6378137,298.257223563]') < 50
AND (select count(*) from deals_user_actions dua where dua.deal_id = d.id) = 10
更新1:如果您想显示操作数,请改为加入汇总数据:
SELECT d.id, d.title, dua.actions
FROM deals d
JOIN locations l ON l.id = d.location_id
JOIN
(
select deal_id, count(*) as actions
from deals_user_actions
group by deal_id
having actions = 10
) dua ON dua.deal_id = d.id
WHERE ST_Distance_Spheroid(ST_MAKEPOINT(l.longitude, l.latitude),
ST_MAKEPOINT(18, 59),
'SPHEROID[\"WGS 84\",6378137,298.257223563]') < 50
更新2 :为了完整起见,我向您展示您的原始查询仅使用GROUP BY和HAVING略微修改。你看,当要求汇总结果(这里是COUNT(*)
)时,你不能在WHERE中对表的记录起作用,而是在HAVING中对聚合组起作用。
但是,如上所示,加入聚合是一个好习惯,而不是先加入表格然后聚合,如下所示。 (对于后者,当您不得不使用来自多个表的聚合时,您很容易遇到问题。)
SELECT
d.id,
d.title,
COUNT(dua.deal_id) AS numUserActions
FROM deals d
JOIN locations l ON l.id = d.location_id
JOIN deals_user_actions dua ON dua.deal_id = d.id
WHERE ST_Distance_Spheroid(ST_MAKEPOINT(l.longitude, l.latitude),
ST_MAKEPOINT(18, 59),
'SPHEROID[\"WGS 84\",6378137,298.257223563]') < 50
GROUP BY d.id, d.title
HAVING numUserActions = 10