繁体   English   中英

SQL选择计数组与零计数

[英]sql select count group by with zero counts

在jsf中,我有一个命名查询来对数据进行计数和分组。

@NamedQuery(name = "Zdarzenie.SelectCount", query = "select new Answer((type(z)) ,month(z.data), year(z.data), count(z)) from Eventz where type(z) in :givenEvents and z.data >= :dataOd and z.data<= :datDo group by Month(z.data), year(z.data), type(z) order by month(z.data), year(z.data) asc "),

它运作良好-在给定期间内每月计算事件。 但是-当计数为'0'时,它只会在结果列表中跳过该计数。 因此,效果看起来像:

[ADD, 1, 2013, 33]
[ADD, 2, 2013, 25]
[REMOVE 2, 2013, 1]

我需要它看起来像这样:

[ADD, 1, 2013, 33]
[REMOVE, 1, 2013, 0]
[ADD, 2, 2013, 25]
[REMOVE 2, 2013, 1]

谢谢你的帮助

为了简化示例,如果您的表T包含:

Type   | Month | Year
-------+-------+-------
ADD    |   1   | 2013
ADD    |   1   | 2013
REMOVE |   1   | 2013
REMOVE |   1   | 2013
ADD    |   2   | 2013
ADD    |   2   | 2013
REMOVE |   3   | 2013

如您所知,如果您这样做:

SELECT  Type, Month, Year, COUNT(*) AS Count
FROM    T
GROUP BY Type, Month, Year;

你会得到:

Type   | Month | Year | Count
-------+-------+------+-------
ADD    |   1   | 2013 |   2
REMOVE |   1   | 2013 |   2
ADD    |   2   | 2013 |   2
REMOVE |   3   | 2013 |   1

因此,您错过了第3个月的ADD和第2个月的REMOVE计数。这是因为数据库无法包含不存在的结果。

如何解决这个问题取决于您希望结果显示的方式,如果要所有可能的组合,则需要使用类似以下内容的方法:

SELECT  Types.Type, Years.Year, Months.Month
FROM    (SELECT DISTINCT Type FROM T) AS Types
        CROSS JOIN (SELECT DISTINCT Year FROM T) AS Years
        CROSS JOIN (SELECT DISTINCT Month FROM T) AS Months

这将给出所有3列的笛卡尔乘积:

Type   | Month | Year
-------+-------+-------
ADD    |   1   | 2013
ADD    |   2   | 2013
ADD    |   3   | 2013
REMOVE |   1   | 2013
REMOVE |   2   | 2013
REMOVE |   3   | 2013

然后,您可以左加入原始表以获取计数:

SELECT  Types.Type, Years.Year, Months.Month, COUNT(T.Type) AS Count
FROM    (SELECT DISTINCT Type FROM T) AS Types
        CROSS JOIN (SELECT DISTINCT Year FROM T) AS Years
        CROSS JOIN (SELECT DISTINCT Month FROM T) AS Months
        LEFT JOIN T
            ON T.Type = Types.Type
            AND T.Year = Years.Year
            AND T.Month = Months.Month;

这将产生期望的结果:

Type   | Month | Year | Count
-------+-------+------+--------
ADD    |   1   | 2013 |   2
ADD    |   2   | 2013 |   2
ADD    |   3   | 2013 |   0
REMOVE |   1   | 2013 |   2
REMOVE |   2   | 2013 |   0
REMOVE |   3   | 2013 |   1

由于问题中未提供任何内容,因此我尝试使上述内容尽可能地不特定于DBMS,但可能需要对DBMS进行一些细微调整。

至于其余的问题,我认为您无法从数据库获取不存在的数据。 同样,任何复杂的查询都不是恕我直言的解决方案,因为没有人会理解它们+您可能会遇到性能问题(您/您的团队将花费更多的时间来调试这些SQL查询,而不是您计划的时间)。

从数据库中获取所需的数据后,唯一的解决方案是用Java填充所需的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM