【问题标题】:SQL CASE Statement and Multiple ConditionsSQL CASE 语句和多个条件
【发布时间】:2018-12-07 23:52:39
【问题描述】:

我正在编写一个基本的 SQL 查询,以在基于云的报告工具中构建一个表,该工具支持各种 SQL“方言”(没有对数据库的服务器端访问)。我有 SQL 的工作知识,并且需要能够为特定的可视化构建基本表。具体来说,我需要可视化/量化原始表中逗号分隔列表中值的每个唯一实例。在我的示例中,Col4 具有不同顺序的值 a、b、c、d,需要对其进行计数和可视化以显示每个值在每个日期出现的次数(Col1)。

原来的表格是这样的:

我正在使用 CASE 语句,因此我可以在新表中操作 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

所需的表格(要使可视化工作看起来像这样):

这样,每次“a”和“b”出现时,视觉效果都会显示,无论它们在原始表中 Col4 中逗号分隔列表中的位置如何(这样我就可以显示“a”和“b”每月)

问题是,此 CASE 语句仅在满足第一个 WHEN 条件时才返回 TRUE。例如,我看到的结果是,如果一个单元格同时包含“a”和“b”,它将只返回遇到的第一个 TRUE 条件,并且不会从同一个逗号分隔列表中返回“b”。相反,如果“b”列在“a”之前(排序是可变的,因为选择来自最终用户填充的选项列表),则“b”返回“TRUE”并且“a”被忽略。

本质上,我如何调整此查询以返回而不考虑位置以及两个值是否在同一个逗号分隔列表中?希望这是有道理的,谢谢!

【问题讨论】:

  • 例如,当Col3 显示c, a, b 时,您期望哪个输出?
  • 道歉 - 写问题并忘记了所需的输出。使用此信息编辑了原始问题。感谢您的帮助!
  • 您的 SQL 引擎是否支持表值函数?意思是,你能定义你自己的返回集合的函数吗?
  • 不是在构建查询表时(它支持字符串、数学、聚合和数据函数)——至少据我了解。谢谢!

标签: sql case-statement


【解决方案1】:

由于您想从同一原始行返回多行,您需要一个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

【讨论】:

  • 感谢您的回答!阅读您的答案后,我意识到我需要 UNION ALL 在每个 SELECT 语句下。我还将每个 CASE WHEN 语句分离为它自己的 SELECT 语句,并结合 UNION ALL,我能够得到正确的结果。干杯!
【解决方案2】:

一段时间以来,我已经在 Microsoft SQL Server 中使用 STUFFFOR 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

输出:

【讨论】:

    【解决方案3】:

    我重新阅读了您的问题,我想我现在理解得更好了。您希望将abc 转换为自定义标签,对吧?

    您可以为此多次调用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
    

    【讨论】:

    • 道歉 - 写问题并忘记了所需的输出。使用此信息编辑了原始问题。感谢您的帮助!
    猜你喜欢
    • 2014-09-21
    • 1970-01-01
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多