Заявката ви вече ще работи - освен че се сблъсквате с конфликти с имена или просто обърквате изходната колона (CASE
израз) с изходна колона result
, който има различно съдържание.
...
GROUP BY model.name, attempt.type, attempt.result
...
Трябва да GROUP BY
вашият CASE
израз вместо вашата изходна колона:
...
GROUP BY model.name, attempt.type
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
...
Или посочете псевдоним на колона което е различно от всяко име на колона в FROM
списък - или тази колона има предимство:
SELECT ...
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
...
SQL стандартът е доста особен в това отношение. Цитирайки ръководството тук:
Името на изходна колона може да се използва за препращане към стойността на колоната в
ORDER BY
иGROUP BY
клаузи, но не и вWHERE
илиHAVING
клаузи; там трябва да напишете израза вместо това.
И:
Ако
ORDER BY
изразът е просто име, което съответства както на име на изходна колона, така и на име на входна колона,ORDER BY
ще го интерпретира като име на изходната колона. Това е обратното на избора, койтоGROUP BY
ще направите в същата ситуация. Това несъответствие е направено, за да бъде съвместимо със стандарта SQL.
Удебелен наблягам мой.
Тези конфликти могат да бъдат избегнати чрез използване на позиционни препратки (редни номера) в GROUP BY
и ORDER BY
, препраща към елементи в SELECT
списък отляво надясно. Вижте решението по-долу.
Недостатъкът е, че това може да е по-трудно за четене и уязвимо за редакции в SELECT
списък (може да забравите да адаптирате съответно позиционните препратки).
Но вие не трябва да добавите колоната day
към GROUP BY
клауза, стига да съдържа постоянна стойност (CURRENT_DATE-1
).
Пренаписан и опростен с подходящ JOIN синтаксис и позиционни препратки, може да изглежда така:
SELECT m.name
, a.type
, CASE WHEN a.result = 0 THEN 0 ELSE 1 END AS result
, CURRENT_DATE - 1 AS day
, count(*) AS ct
FROM attempt a
JOIN prod_hw_id p USING (hard_id)
JOIN model m USING (model_id)
WHERE ts >= '2013-11-06 00:00:00'
AND ts < '2013-11-07 00:00:00'
GROUP BY 1,2,3
ORDER BY 1,2,3;
Също така имайте предвид, че избягвам името на колоната time
. Това е запазена дума и никога не трябва да се използва като идентификатор. Освен това вашето "време" очевидно е timestamp
или date
, така че това е доста подвеждащо.