我正在尝试使用JOIN从2个表中进行选择:
SELECT a.*, COUNT(b.*) as num_topups FROM customer_sms a JOIN customer_sms_topups b ON a.sequence = b.sms_account WHERE a.sequence = b.sms_account AND a.auto_topup_credits > '0' AND a.auto_topup_threshold <= a.balance AND MONTH(b.datetime) = '10' AND YEAR(b.datetime) = '2018' AND num_topups < a.auto_topup_maximum;
但是我想我算错了:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*) as num_topups FROM customer_sms a JOIN customer_sms_topups b ON a.sequence = ' at line 1
我需要计数才能将customer_sms_topups中的行数与a.auto_topup_maximum
答案 0 :(得分:1)
对于计数,应使用count(*)
但是您在select中有其他列未参与聚合功能,并且在group by中未提及
在SQL中已弃用此功能,在大多数数据库中均不起作用,在最新版本的mysql中dpn不起作用
适用于该版本的版本,此列的结果无法预测
所以你应该
或在select中使用显式列名称并添加适当的group by子句,例如:
SELECT a.col1
, a.col2
, COUN(T*) as num_topups
FROM customer_sms a
JOIN customer_sms_topups b ON a.sequence = b.sms_account
WHERE a.sequence = b.sms_account
AND a.auto_topup_credits > '0'
AND a.auto_topup_threshold <= a.balance
AND MONTH(b.datetime) = '10'
AND YEAR(b.datetime) = '2018'
group by a.col1 , a.col2
或对您选择的所有列使用聚合功能
SELECT min(a.col1)
, min(a.col2 )
, COUNT(*) as num_topups
FROM customer_sms a
JOIN customer_sms_topups b ON a.sequence = b.sms_account
WHERE a.sequence = b.sms_account
AND a.auto_topup_credits > '0'
AND a.auto_topup_threshold <= a.balance
AND MONTH(b.datetime) = '10'
AND YEAR(b.datetime) = '2018'
答案 1 :(得分:0)
可以在HAVING
子句中对聚合表达式进行比较,但在WHERE
子句中则不允许。
通常,在带有聚合的查询中,我们通常有一个GROUP BY
子句,除非我们希望将结果折叠成一行。
没有实际的说明(如示例数据和预期结果所示),我们只是猜测查询应返回什么结果。
我的猜测是我们正在寻找该查询将返回的结果:
SELECT a.*
, COUNT(b.sms_account) AS num_topups
FROM customer_sms a
LEFT
JOIN customer_sms_topups b
ON b.sms_account = a.sequence
AND b.datetime >= '2018-10-01'
AND b.datetime < '2018-10-01' + INTERVAL 1 MONTH
WHERE a.auto_topup_credits > '0'
AND a.auto_topup_threshold <= a.balance
GROUP
BY a.sequence
, a.auto_topup_credits
, a.auto_topup_threshold
, a.balance
, ...
HAVING COUNT(b.sms_account) < a.auto_topup_maximum
ORDER
BY a.sequence
, a.auto_topup_credits
, a.auto_topup_threshold
, a.balance
, ...
如果我们要排除num_topups
具有“零”的行,则可以删除LEFT
关键字。
还有其他几种查询模式可以返回等效结果。
例如,条件聚合:
SELECT a.*
, SUM(IF(b.datetime >= '2018-10-01' AND b.datetime < '2018-10-01' + INTERVAL 1 MONTH
,1,0)
) AS num_topups
FROM customer_sms a
LEFT
JOIN customer_sms_topups b
ON b.sms_account = a.sequence
WHERE a.auto_topup_credits > '0'
AND a.auto_topup_threshold <= a.balance
GROUP
BY a.sequence
, a.auto_topup_credits
, a.auto_topup_threshold
, a.balance
, ...
HAVING num_topups < a.auto_topup_maximum
ORDER
BY a.sequence
, a.auto_topup_credits
, a.auto_topup_threshold
, a.balance
, ...
或者我们可以在内联视图中进行聚合,然后进行联接。使用这种模式,我们可以避免在外部查询上使用GROUP BY子句。
SELECT a.*
, c.num_topups
FROM customer_sms a
LEFT
JOIN ( SELECT b.sms_account AS sms_account
, SUM(1) AS num_topups
FROM customer_sms_topups b
WHERE b.datetime >= '2018-10-01'
AND b.datetime < '2018-10-01' + INTERVAL 1 MONTH
GROUP
BY b.sms_account
) c
ON c.sms_account = a.sequence
AND IFNULL(c.num_topups,0) < a.auto_topup_maximum
WHERE a.auto_topup_credits > '0'
AND a.auto_topup_threshold <= a.balance
ORDER
BY a.sequence
, a.auto_topup_credits
, a.auto_topup_threshold
, a.balance
, ...
SELECT
列表中的相关子查询也可以用于获取计数。通过避免联接到子表,我们可以在外部查询中不需要GROUP BY
子句的情况下获得相关行的计数:
SELECT a.*
, ( SELECT COUNT(1)
FROM customer_sms_topups b
WHERE b.sms_account = a.sequence
AND b.datetime >= '2018-10-01'
AND b.datetime < '2018-10-01' + INTERVAL 1 MONTH
) AS num_topups
FROM customer_sms a
WHERE a.auto_topup_credits > '0'
AND a.auto_topup_threshold <= a.balance
HAVING num_topups < a.auto_topup_maximum
ORDER
BY a.sequence
, a.auto_topup_credits
, a.auto_topup_threshold
, a.balance
, ...