#sql #group-by #case #aggregate-functions #teradata
#sql #группировка по #случай #агрегатные функции #терадата
Вопрос:
Я нахожусь в TeraData, у меня есть два поля f1, f2, и мне нужна следующая логика:
sel
'blah' as x1,
case when count(distinct f1) = count(distinct f2)
then(case when char(trim(f1)) between 1 and 25
then 'OK'
else 'DEFECT_1'
end)
else 'DEFECT_2'
end as x2,
count(x2) as x3
from table
group by 1, 2
Это выдает ошибку, поскольку агрегатные функции не разрешены в операторах group by. Как я могу обойти это, чтобы получить проверку количества перед проверкой длины?
Спасибо!
Редактировать для уточнения:
Это одна часть более крупного SQL, которая проверяет различное форматирование в наборе данных. Вывод представляет собой набор объединений (по одному для каждой проверки), каждая из форм:
check_n | OK | count(OK)
check_n | DEFECT_1 | count(DEFECT_1)
check_n | ... | ...
check_n | DEFECT_m | count(DEFECT_m)
check_n 1| ... | ...
Но для этого конкретного бита я хочу получить следующий результат:
check_k | OK | count(OK)
check_k | DEFECT_1 | count(DEFECT_1)
check_k | DEFECT_2 | NULL
Ответ №1:
Я не думаю, что есть способ получить такой результат с помощью простого запроса, но это должно сработать (хотя это определенно не очень эффективно).:
sel
'blah' as x1,
case when (SELECT count(distinct f1) - count(distinct f2) FROM table) = 0
then(case when char(trim(f1)) between 1 and 25
then 'OK'
else 'DEFECT_1'
end)
else 'DEFECT_2'
end as x2,
count(x2) as x3
from table
group by 1, 2
Более сложным, но и более эффективным должно быть следующее: вычислите все три возможных результата в одной строке, а затем выполните условное соединение с двухстрочной таблицей (здесь используется sys_calendar):
SELECT
x1,
CASE
WHEN is_equal = 'N' THEN 'Defect_2'
WHEN n = 1 THEN 'Defect_1'
ELSE 'OK'
END,
CASE
WHEN is_equal = 'N' THEN cnt
WHEN n = 1 THEN cnt - cntcase
ELSE cnt
END AS x
FROM
(
SEL 'blah' AS x1,
COUNT(CASE WHEN (CHAR(TRIM(f1))) BETWEEN 1 AND 25 THEN 1 END) AS cntcase,
COUNT(*) AS cnt,
CASE WHEN COUNT(DISTINCT f1) = COUNT(DISTINCT f2)
THEN 'Y'
ELSE 'N'
END AS is_equal
FROM TABLE
GROUP BY 1
) AS dt
JOIN (SELECT day_of_calendar AS n FROM sys_calendar.CALENDAR WHERE n BETWEEN 1 AND 2) AS t2
ON (n = 1 OR (is_equal = 'Y'))
AND x > 0