2013-12-05 3 views
0

В jsf У меня есть именованный запрос, который подсчитывает и группирует данные.sql select count group by with zero counts

@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», он просто пропускает это в списке результатов. Таким образом, reulst выглядеть следующим образом:

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

Спасибо за вашу помощь

+0

Я думаю, для этого вам нужно поставить код проверки – Freak

+0

Я не так хорош с sql - вы можете предложить запрос с проверкой? –

+0

Это потому, что наличие count 0 означает, что у вас нет строк на таблице, содержащей эти значения. Вы не можете иметь строки результата, которых нет в таблице. Говорить по-другому. Как должна знать база данных о том, что вы хотите получить результат [УДАЛИТЬ, 1, 2013, 0]? Как он должен знать, что вы не хотите видеть результат [FOOBAR, -7, 1353, 0]? Эта комбинация также имеет нулевой счет на столе. – OllesEtta

ответ

2

Как я думаю, с этим запросом вы просто не можете получить несуществующие данные из БД. Также любые сложные запросы - это IMHO, а не решение, потому что никто не поймет их +, вы можете столкнуться с проблемами производительности (вы/ваша команда потратит больше времени для отладки этих SQL-запросов, чем вы планировали).

Единственным решением было бы заполнить необходимые данные на Java после того, как вы извлечете его из БД.

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 и REMOVE за месяц 2. Это происходит потому, что база данных не может включать в себя результаты, которые не существуют.

Как решить это зависит от того, как именно вы хотите, чтобы ваши результаты, чтобы показать, если вы хотите, чтобы все возможные комбинации, вам нужно будет использовать что-то вроде:

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 

Это даст cartesion произведение всех 3 колонки:

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 

Я попытался сделать выше в качестве СУБД inspecific, насколько это возможно, так как никто не был поставлен в вопросе, но это может потребовать незначительных настроек для вашей СУБД.

+0

Я дам ему попробовать :) спасибо –

+0

это решение хорошо для sql - но я не пишу запрос в простой sql, так что это не помогает мне. Спасибо за помощь :) –

+0

+1 от меня, так как это интересное решение (хотя на практике им нужно очень много усилий) –