SQL CASE 语句和多个条件
SQL CASE Statement and Multiple Conditions
我正在编写一个基本的 SQL 查询以在基于云的报告工具中构建一个 table,它支持范围广泛的 SQL "dialects"(没有服务器端访问数据库)。我有 SQL 的工作知识,需要能够为特定的可视化构建基本的 table。具体来说,我需要 visualize/quantify 以逗号分隔的列表中的每个值的唯一实例与原始 table。对于我的示例,Col4 具有不同顺序的值 a、b、c、d,需要对其进行计数和可视化以显示每个值在每个日期 (Col1) 中出现的次数。
原来的table是这样的:
我正在使用 CASE 语句,因此我可以在新的 table 中操作 Col4 输出的标签,使其更易于可视化。
这是我的查询的简短示例:
SELECT
Col1, CoL2,
CASE
WHEN Col4 LIKE '%a'
THEN 'custom label for a'
WHEN Col4 LIKE '%b%'
THEN 'Custom Label for b'
END AS 'Column Label'
FROM
Original_Table
所需的 table(可视化效果应如下所示):
这样,每次 "a" 和 "b" 都会显示视觉效果,而不管它们在原始 table 中 Col4 的逗号分隔列表中的位置(所以我可以显示每月 "a" 和 "b" 的出现次数)
问题是,只有满足第一个 WHEN 条件之一时,此 CASE 语句才 return 为 TRUE。例如,我看到的结果是,如果一个单元格同时包含 "a" 和 "b",它只会 return 遇到的第一个 TRUE 条件,并且不会 return "b" 来自相同的逗号分隔列表。相反,如果 "b" 在 "a" 之前列出(顺序是可变的,因为选择来自最终用户填充的选择列表),那么 "b" 是 returned "TRUE" 和 "a" 被忽略。
本质上,我如何将此查询调整为 return 而不管位置如何,也不管两个值是否在同一个逗号分隔列表中?希望这是有道理的,谢谢!
我已经在 Microsoft SQL 服务器中使用 STUFF
和 FOR XML PATH('')
准备了一段时间的逗号分隔列表。
如果这个确切的语法对您不起作用,您仍然可以找到一些关于它如何工作的有用信息here。
DECLARE @LetterTypes TABLE (Type CHAR(10))
INSERT @LetterTypes
VALUES
('Consonant'),
('Vowell')
DECLARE @Letters TABLE (Letter CHAR(1) NOT NULL, Type VARCHAR(10) NOT NULL)
INSERT @Letters
VALUES
('A','Vowell'),
('B','Consonant'),
('C','Consonant'),
('D','Consonant'),
('E','Vowell'),
('F','Consonant'),
('G','Consonant'),
('H','Consonant'),
('I','Vowell'),
('J','Consonant'),
('K','Consonant'),
('L','Consonant'),
('M','Consonant'),
('N','Consonant'),
('O','Vowell'),
('P','Consonant'),
('Q','Consonant'),
('R','Consonant'),
('S','Consonant'),
('T','Consonant'),
('U','Vowell'),
('V','Consonant'),
('W','Consonant'),
('X','Consonant'),
('Y','Consonant'),
('Z','Consonant')
SELECT
Type,
STUFF
(
(
SELECT ', ' + Letter
FROM @Letters L
WHERE LT.Type = L.Type
ORDER BY L.Letter
FOR XML PATH('')
), 1, 2, ''
) AS Letters
FROM @LetterTypes LT
输出:
我重新阅读了你的问题,我想我现在理解得更好了。您希望将 a
、b
和 c
转换为自定义标签,对吗?
为此,您可以多次调用 REPLACE
。忍耐一下!
SELECT
Col1,
CoL2,
REPLACE(
REPLACE(
REPLACE(Col4,
'a', 'Custom Label for a'),
'b', 'Custom Label for b'),
'c', 'Custom Label for c') as ReLabeledCol4
FROM Original_Table
因为你想return来自同一个原始行的多行,你需要一个UNION ALL
SELECT Col1, 'Custom Label for a' AS Col4
FROM Original_Table
WHERE Col4 LIKE '%a%'
UNION ALL
SELECT Col1, 'Custom Label for b' AS Col4
FROM Original_Table
WHERE Col4 LIKE '%b%'
ORDER BY Col1, Col4
我正在编写一个基本的 SQL 查询以在基于云的报告工具中构建一个 table,它支持范围广泛的 SQL "dialects"(没有服务器端访问数据库)。我有 SQL 的工作知识,需要能够为特定的可视化构建基本的 table。具体来说,我需要 visualize/quantify 以逗号分隔的列表中的每个值的唯一实例与原始 table。对于我的示例,Col4 具有不同顺序的值 a、b、c、d,需要对其进行计数和可视化以显示每个值在每个日期 (Col1) 中出现的次数。
原来的table是这样的:
我正在使用 CASE 语句,因此我可以在新的 table 中操作 Col4 输出的标签,使其更易于可视化。
这是我的查询的简短示例:
SELECT
Col1, CoL2,
CASE
WHEN Col4 LIKE '%a'
THEN 'custom label for a'
WHEN Col4 LIKE '%b%'
THEN 'Custom Label for b'
END AS 'Column Label'
FROM
Original_Table
所需的 table(可视化效果应如下所示):
这样,每次 "a" 和 "b" 都会显示视觉效果,而不管它们在原始 table 中 Col4 的逗号分隔列表中的位置(所以我可以显示每月 "a" 和 "b" 的出现次数)
问题是,只有满足第一个 WHEN 条件之一时,此 CASE 语句才 return 为 TRUE。例如,我看到的结果是,如果一个单元格同时包含 "a" 和 "b",它只会 return 遇到的第一个 TRUE 条件,并且不会 return "b" 来自相同的逗号分隔列表。相反,如果 "b" 在 "a" 之前列出(顺序是可变的,因为选择来自最终用户填充的选择列表),那么 "b" 是 returned "TRUE" 和 "a" 被忽略。
本质上,我如何将此查询调整为 return 而不管位置如何,也不管两个值是否在同一个逗号分隔列表中?希望这是有道理的,谢谢!
我已经在 Microsoft SQL 服务器中使用 STUFF
和 FOR XML PATH('')
准备了一段时间的逗号分隔列表。
如果这个确切的语法对您不起作用,您仍然可以找到一些关于它如何工作的有用信息here。
DECLARE @LetterTypes TABLE (Type CHAR(10))
INSERT @LetterTypes
VALUES
('Consonant'),
('Vowell')
DECLARE @Letters TABLE (Letter CHAR(1) NOT NULL, Type VARCHAR(10) NOT NULL)
INSERT @Letters
VALUES
('A','Vowell'),
('B','Consonant'),
('C','Consonant'),
('D','Consonant'),
('E','Vowell'),
('F','Consonant'),
('G','Consonant'),
('H','Consonant'),
('I','Vowell'),
('J','Consonant'),
('K','Consonant'),
('L','Consonant'),
('M','Consonant'),
('N','Consonant'),
('O','Vowell'),
('P','Consonant'),
('Q','Consonant'),
('R','Consonant'),
('S','Consonant'),
('T','Consonant'),
('U','Vowell'),
('V','Consonant'),
('W','Consonant'),
('X','Consonant'),
('Y','Consonant'),
('Z','Consonant')
SELECT
Type,
STUFF
(
(
SELECT ', ' + Letter
FROM @Letters L
WHERE LT.Type = L.Type
ORDER BY L.Letter
FOR XML PATH('')
), 1, 2, ''
) AS Letters
FROM @LetterTypes LT
输出:
我重新阅读了你的问题,我想我现在理解得更好了。您希望将 a
、b
和 c
转换为自定义标签,对吗?
为此,您可以多次调用 REPLACE
。忍耐一下!
SELECT
Col1,
CoL2,
REPLACE(
REPLACE(
REPLACE(Col4,
'a', 'Custom Label for a'),
'b', 'Custom Label for b'),
'c', 'Custom Label for c') as ReLabeledCol4
FROM Original_Table
因为你想return来自同一个原始行的多行,你需要一个UNION ALL
SELECT Col1, 'Custom Label for a' AS Col4
FROM Original_Table
WHERE Col4 LIKE '%a%'
UNION ALL
SELECT Col1, 'Custom Label for b' AS Col4
FROM Original_Table
WHERE Col4 LIKE '%b%'
ORDER BY Col1, Col4