MySQL如何将WHERE子句应用于除一个之外的所有选定列?

时间:2016-03-10 14:30:17

标签: mysql

我正在整理专栏并按专栏对其进行分组"水果"像这样:(基于我的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

所以,我的问题是如何编写一个查询,它可以获得所有结果,无论日期如何,但只按日期过滤金额和价格列?

4 个答案:

答案 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