我正在整理专栏并按专栏对其进行分组"水果"像这样:(基于我的previous question on SO)
SELECT `fruits`, sum(amount), sum(price)
FROM `accounts`
GROUP BY fruits
我现在已经在表格中添加了一个日期列,我试图按照这样的日期过滤结果:
SELECT `fruits`, sum(amount), sum(price)
FROM `accounts`
WHERE `userid` = 1 AND `date` BETWEEN "2010-11-01" AND "2015-12-22"
GROUP BY fruits
这很好用,我得到了过滤后的结果。但是,如果在两个日期之间没有输入水果,它自然不会显示,因为WHERE子句还包括fruits
。
所以,我的问题是如何编写一个查询,它可以获得所有结果,无论日期如何,但只按日期过滤金额和价格列?
答案 0 :(得分:2)
即使世界'几种方法。一种是使用条件聚合。删除谓词,并将条件测试移动到SELECT列表中的表达式。例如,像这样:
SELECT a.fruits
, SUM( IF(a.userid = 1 AND a.date BETWEEN '2010-11-01' AND '2015-12-22'
,a.amount,0)
) AS `tot_amount`
, SUM( IF(a.userid = 1 AND a.date BETWEEN '2010-11-01' AND '2015-12-22'
,a.price,0)
) AS `tot_price`
FROM `accounts` a
GROUP BY a.fruits
其他方法将使用行源来返回您想要返回的fruits
的值,然后使用"外连接"来自原始查询的总计。或者对于相当少量的行,您可以在SELECT列表中使用相关子查询。
我们假设这会返回您要返回的fruits
集:
SELECT s.fruits
FROM `accounts` s
GROUP BY s.fruits
我们可以将它包装在parens中,并将其用作行源,就像它是一个表。作为一个简单的例子:
SELECT f.fruits
FROM (
SELECT s.fruits
FROM `accounts` s
GROUP BY s.fruits
) f
现在我们可以对您的原始查询执行相同的操作,将其包装在parens中并使其成为内联视图:
SELECT f.fruits
, IFNULL(t.tot_amount,0) AS tot_amount
, IFNULL(t.tot_price,0) AS tot_price
FROM (
SELECT s.fruits
FROM `accounts` s
GROUP BY s.fruits
) f
LEFT
JOIN (
-- original query here
SELECT a.`fruits`
, sum(a.amount) AS tot_amount
, sum(a.price) AS tot_price
FROM `accounts` a
WHERE a.`userid` = 1
AND a.`date` BETWEEN '2010-11-01' AND '2015-12-22'
GROUP BY a.fruits
) t
ON t.fruits = f.fruits
答案 1 :(得分:1)
您可以使用左连接执行此操作:
SELECT t.`fruits`,sum(coalesce(s.amount,0)),sum(coalesce(s.price,0))
FROM(SELECT DISTINCT `fruits` FROM `accouts`) t
LEFT OUTER JOIN `accounts` s
ON(t.`fruits` = s.`fruits` AND s.`userid` = 1
AND s.`date` BETWEEN "2010-11-01" AND "2015-12-22")
GROUP BY t.`fruits`
答案 2 :(得分:1)
试试这个:
SELECT
`fruits`,
sum((`date` BETWEEN "2010-11-01" AND "2015-12-22") * amount) total_amount,
sum((`date` BETWEEN "2010-11-01" AND "2015-12-22") * price) total_price
FROM `accounts`
WHERE `userid` = 1
GROUP BY fruits
答案 3 :(得分:-1)
你可以做到这一点:
SELECT a1.`fruits`, sum(a1.amount), sum(a1.price)
FROM `accounts` a1
LEFT OUTER JOIN `accounts` a2 ON a1.fruits = a2.fruits
AND a2.`userid` = 1 AND a2.`date` BETWEEN "2010-11-01" AND "2015-12-22"
GROUP BY a1.fruits