MySQL group by包含空行

时间:2018-01-23 01:12:19

标签: mysql sql stored-procedures

我有一个查询,它使用日历表来获取当月每天的订单数量。这包括所订购产品的面额及其发放的总金额。

SELECT
    reward.denomination,
    SUM(CASE WHEN dateCreated IS NULL THEN 0 ELSE 1 END) as totalRewards,
    SUM(reward.denomination) as totalIssued
FROM
    calendar as c
LEFT JOIN reward
   ON DAY(reward.dateCreated) = c.cday
   AND MONTH(reward.dateCreated) = c.cmonth
   AND YEAR(reward.dateCreated) = c.cyear
   AND reward.userID = 1
WHERE
    c.cmonth = MONTH(CURRENT_DATE())
AND 
    c.cyear = YEAR(CURRENT_DATE())
AND
    c.cday <= DAY(CURRENT_DATE())
 GROUP BY reward.denomination
 ORDER BY reward.denomination ASC

enter image description here

在此输出中,第一行显示0总奖励,然后null显示其他两列。

但是,总共只有4条记录应该处理(在结果集中正确显示。

为什么要包含第一行,如何摆脱它?

1 个答案:

答案 0 :(得分:0)

您的left join将所有行保留在calendar中。对于不匹配的任何行,将保留rewards中的列。 。 。但列是NULL。这样的行将是用户1没有奖励的日期。

您的汇总密钥位于rewards,因此不匹配的密钥为NULL

SQL正在做它应该做的事情。你可能只想要一个inner join

我认为如果没有calendar表,您的查询会更简单:

SELECT r.denomination, COUNT(*) as totalRewards,
       SUM(r.denomination) as totalIssued
FROM reward r
WHERE r.userID = 1 AND
      r.dateCreated <= CURRENT_DATE() AND
      r.dateCreated >= CURRENT_DATE() - INTERVAL (1 - DAY(CURRENT_DATE()) DAY
GROUP BY r.denomination
ORDER BY r.denomination ASC;

除了简化查询外,还允许您使用更简单的日期算法。作为奖励,这可以利用rewards(userId, dateCreated)上的索引。