Вложенный случай, когда: проверка количества, затем проверка формата

#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