SQL Case中的多个条件

Posted

技术标签:

【中文标题】SQL Case中的多个条件【英文标题】:Multipel condition at SQL Case 【发布时间】:2017-11-14 07:28:21 【问题描述】:

我有 3 个表要加入:

ALERT_CASE_HEADER
 - alert_key
ALERT_ITEM
- entity_key
-status_id
-entity_name='Active Alert'
STATUSES
-name
-id

两个警报表都使用 alert_key 和 entity_key 进行链接。仅当两个键的值相同且每个可用状态名称为 entity_name='Active Alert' 时,才会发生大小写求和。并且表 STATUSES 中的 id 列链接到 ALERT_ITEM.status_id

我可以这样做吗?我尝试运行脚本,但似乎很慢。

SELECT 
  SUM(
    CASE
      WHEN s.name = 'Pending' 
      AND ach.alert_key = ai.entity_key 
      AND ai.entity_name = 'Active Alert' 
      THEN 1 
      ELSE 0 
    END
  ) AS PENDING, SUM(
    CASE
      WHEN s.name = 'new' 
      AND ach.alert_key = ai.entity_key 
      AND ai.entity_name = 'Active Alert' 
      THEN 1 
      ELSE 0 
    END
  ) AS NEW, SUM(
    CASE
      WHEN s.name = 'cancel' 
      AND ach.alert_key = ai.entity_key 
      AND ai.entity_name = 'Active Alert' 
      THEN 1 
      ELSE 0 
    END
  ) AS CANCEL 
FROM
  STATUSES s, ALERT_CASE_HEADER ach, ALERT_ITEM ai;

(来自提问者 2017 年 11 月 14 日 9:53 的回答,应该是一个编辑:)

我使用的脚本如下,只关注 2 个连接语句。第二个连接有效,但不是第一个。

 SELECT CUS.ORGUNIT_CODE AS ORGANIZATION_UNITS,
  SUM(
    CASE
      WHEN S.name = 'Pending' THEN 1 ELSE 0 
    END
    ) AS PENDING_AUTOCLOSURE, 
  SUM(
    CASE
      WHEN S.name = 'New' THEN 1 ELSE 0 
    END
    ) AS NEW, 
  SUM(
    CASE
      WHEN S.name = 'Under Investigation' THEN 1 ELSE 0 
    END
  ) AS UNDER_INVESTIGATION,
  SUM(
    CASE
       WHEN S.Name = 'Escalated' THEN 1 ELSE 0
    END
  ) AS ESCALATED,
   SUM(
    CASE
       WHEN S.Name = 'Recommend True Positive' THEN 1 ELSE 0
    END
  ) AS RECOMMEND_TRUE_POSITIVE,
   SUM(
    CASE
       WHEN S.Name = 'Reopen Under Investigation' THEN 1 ELSE 0
    END
  ) AS REOPEN_UNDER_INVESTIGATION
FROM
  STATUSES S,CUSTOMERS CUS,ALERT_ITEM AI
  JOIN ALERT_ITEM AI ON S.ID = AI.STATUS_ID
  JOIN ALERT_CASE_HEADER ACH ON AI.ENTITY_KEY = ACH.ALERT_KEY
WHERE AI.ENTITY_NAME = 'Active Alert'
AND   AI.ORGUNIT_ID = CUS.ORGUNIT_ID
GROUP BY CUS.ORGUNIT_CODE;

【问题讨论】:

我确定你不会期待CROSS JOIN 与其他表的表STATUSES 有什么关系? statuses表和others表有关系吗? 是的,表 STATUSES 中有一个 id 列链接到 ALERT_ITEM.status_id 为了得到更好的解决方案,请添加一些示例数据和预期结果。 Doing a left join with old style joins的可能重复 【参考方案1】:

S.ID 00904 标识符无效

ORA-00904:字符串:无效标识符

原因:输入的列名 丢失或无效。

操作:输入有效的列名。一种 有效的列名必须以字母开头,小于或等于 30 个字符,仅由字母数字字符和 特殊字符 $、_ 和 #。如果它包含其他字符,则 它必须用双引号引起来。它可能不是一个 保留字。

问题存在于这些行中。

FROM
  STATUSES S,CUSTOMERS CUS,ALERT_ITEM AI
  JOIN ALERT_ITEM AI ON S.ID = AI.STATUS_ID
  JOIN ALERT_CASE_HEADER ACH ON AI.ENTITY_KEY = ACH.ALERT_KEY
WHERE AI.ENTITY_NAME = 'Active Alert'
    第二行:别名S是为表STATUSES定义的 第三行:别名S再次用于列S.ID该列无效 表示表STAUTUSES没有名为ID的列。 第二行:您又添加了 2 个表格,并且再次使用逗号。 这很糟糕,非常非常非常糟糕。切勿将 ANSI 样式连接与“逗号语法”混用,混用这些样式会导致噩梦。 第二行和第三行:你重复了ALERT_ITEM AI

.

FROM
  STATUSES S

  ,CUSTOMERS CUS  /* change this to explicit join */

  JOIN ALERT_ITEM AI ON S.ID /* <<< wrong column name */   = AI.STATUS_ID

不要在表之间使用逗号。如果你记住这一点,你的 SQL 生活会更轻松。

【讨论】:

感谢您的建议,查询已更改为显式联接且不带逗号。【参考方案2】:

查看您的代码,我建议您以这种方式重构您的查询

使用表之间的连接代替条件以防万一

  SELECT 
    SUM(
      CASE
        WHEN s.name = 'Pending' 
        THEN 1 
        ELSE 0 
      END
    ) AS PENDING
    , SUM(
      CASE
        WHEN s.name = 'new' 
        THEN 1 
        ELSE 0 
      END
    ) AS NEW
   , SUM(
      CASE
        WHEN s.name = 'cancel' 
        THEN 1 
        ELSE 0 
      END
    ) AS CANCEL 
  FROM STATUSES s
  INNER JOIN ALERT_ITEM ai ON s.id = ai.status_id 
      AND  ai.entity_name = 'Active Alert' 
  INNER JOIN  ALERT_CASE_HEADER ach ON ach.alert_key = ai.entity_key 

新的OP代码后更新

不要混合隐式和显式连接

   SELECT CUS.ORGUNIT_CODE AS ORGANIZATION_UNITS,
    SUM(
      CASE
        WHEN S.name = 'Pending' THEN 1 ELSE 0 
      END
      ) AS PENDING_AUTOCLOSURE, 
    SUM(
      CASE
        WHEN S.name = 'New' THEN 1 ELSE 0 
      END
      ) AS NEW, 
    SUM(
      CASE
        WHEN S.name = 'Under Investigation' THEN 1 ELSE 0 
      END
    ) AS UNDER_INVESTIGATION,
    SUM(
      CASE
         WHEN S.Name = 'Escalated' THEN 1 ELSE 0
      END
    ) AS ESCALATED,
     SUM(
      CASE
         WHEN S.Name = 'Recommend True Positive' THEN 1 ELSE 0
      END
    ) AS RECOMMEND_TRUE_POSITIVE,
     SUM(
      CASE
         WHEN S.Name = 'Reopen Under Investigation' THEN 1 ELSE 0
      END
    ) AS REOPEN_UNDER_INVESTIGATION
  FROM
    STATUSES S
    JOIN ALERT_ITEM AI ON S.ID = AI.STATUS_ID
    JOIN ALERT_CASE_HEADER ACH ON AI.ENTITY_KEY = ACH.ALERT_KEY
    INNER JOIN CUSTOMERS CUS ON  AI.ORGUNIT_ID = CUS.ORGUNIT_ID
  WHERE AI.ENTITY_NAME = 'Active Alert'
  GROUP BY CUS.ORGUNIT_CODE;

【讨论】:

我试过了,它得到 s.id 00904. 00000 - "%s: invalid identifier" 您的错误信息不明确.. 显示确切的错误信息并确保您在状态表中有一个 id 列 是的,它有,下面是完整的错误信息: ORA-00904: "s"."id": invalid identifier 00904. 00000 - "%s: invalid identifier" *原因:*操作: 行错误:34 列:32 错误信息是清除无效的列名或缺少列名。当您在 select 语句中引用无效别名时,最常见的“无效标识符”会发生。 ...显示您正在使用的所有代码..(第 34 行错误:32 mysq 答案中的 s.id 不在第 34 行) 我在这个问题上发了一个新帖子来展示我正在使用的脚本【参考方案3】:

你可以用这个:

SELECT 
  SUM(
    CASE
      WHEN s.name = 'Pending' THEN 1 ELSE 0 
    END
    ) AS PENDING, 
  SUM(
    CASE
      WHEN s.name = 'new' THEN 1 ELSE 0 
    END
    ) AS NEW, 
  SUM(
    CASE
      WHEN s.name = 'cancel' THEN 1 ELSE 0 
    END
  ) AS CANCEL 
FROM
  STATUSES s  
  join ALERT_ITEM ai on s.id=ai.status_id
  join ALERT_CASE_HEADER ach on ai.entity_key=ach.alert_key
where ai.entity_name = 'Active Alert'  

【讨论】:

我试过了,它得到 s.id 00904. 00000 - "%s: invalid identifier" s.idai.status_id的数据类型是什么? 为了获得更好的解决方案,请添加一些示例数据和预期结果。 两者都是 NUMBER(38) 我怀疑您的数据有问题。最好请添加一些示例数据和预期结果。

以上是关于SQL Case中的多个条件的主要内容,如果未能解决你的问题,请参考以下文章

SQL 中 where 条件中 in 后面 加 CASE WHEN 语句 报错

使用 Django 的 Case/When 查询集条件来设置多个值?

具有一个条件和多个结果的 SQL CASE

SQL 中 where 条件中 in 后面 加 CASE WHEN 语句 报错

PL/SQL 中 CASE 语句中的堆栈条件

case when用法