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.id
和ai.status_id
的数据类型是什么?
为了获得更好的解决方案,请添加一些示例数据和预期结果。
两者都是 NUMBER(38)
我怀疑您的数据有问题。最好请添加一些示例数据和预期结果。以上是关于SQL Case中的多个条件的主要内容,如果未能解决你的问题,请参考以下文章
SQL 中 where 条件中 in 后面 加 CASE WHEN 语句 报错
使用 Django 的 Case/When 查询集条件来设置多个值?