sql选择计数组由零计数

时间:2013-12-05 10:21:26

标签: java sql jpa

在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 "),

它工作正常 - 它会计算给定时期内每个月的事件。但是 - 当计数是&#39; 0&#39;然后它只是跳过结果列表中的这个。所以,最好的看起来像:

[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]

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

如果你有一个包含以下内容的表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列的cartesion产品:

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

然后,您可以LEFT JOIN原始表格来获取计数:

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进行微调。

答案 1 :(得分:2)

其他我认为使用该查询您无法从DB中获取不存在的数据。此外,任何复杂的查询都是恕我直言,而不是解决方案,因为没有人会理解它们+你可能遇到性能问题(你/你的团队将投入更多时间来调试那些比你计划的SQL查询)。

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