【问题标题】:Nested case when: count check then format check嵌套案例:计数检查然后格式检查
【发布时间】:2014-08-13 15:59:28
【问题描述】:

我在 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

【问题讨论】:

  • 现在查询的编写方式,您甚至不需要 group by。
  • 我没有得到你真正想要的,你能展示一些示例数据和预期结果吗? yu 真的要按那个 CASE 列分组吗?
  • 你确定吗?我尝试在没有 group by 的情况下运行它,我得到“选定的非聚合值必须是关联组的一部分。”
  • 根据您的示例,将有两个互斥结果:DEFECT_2 或(OK 和 DEFECT_1)如果计数匹配,是否正确?

标签: sql group-by case aggregate-functions teradata


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    相关资源
    最近更新 更多