【问题标题】:SQL - CASE Statement if record is NULL because record doesnt exist in tableSQL - 如果记录为 NULL,则 CASE 语句,因为表中不存在记录
【发布时间】:2012-12-06 12:04:15
【问题描述】:

我有一个问题,我认为其中一个问题会在底部解决,但我仍然有问题。问题是我的案例陈述是错误的(但运行时没有错误)但不确定我还缺少什么。

我的目标是,如果 DueDate 为 NULL,因为 Table2 中没有记录,因此我只想将此值显示为“否”而不是“NULL”。我在代码中添加了“IsNull”,但没有解决我的问题。我在这些论坛上看到过 ISNULL() 和 COALEASE() 但无法得到我想要的结果

下面是我的工作代码:

SELECT 
    Client, 
    COUNT(*) AS ReadyRecords, 
    (SELECT COUNT(*) FROM Table1 EPR WHERE actioned=8 AND EPR.Client=Table1.Client) AS Outstanding, 
    (SELECT TOP 1 
        CASE 
            WHEN DueDate < GETDATE() THEN 'Yes' 
            WHEN DueDate IS NULL THEN 'No' 
        ELSE 'No' 
        END AS DueDate
    FROM Table2 GL WHERE GL.Client=Table1.Client ORDER BY DueDate) AS DueDate

    FROM Table1 WHERE Actioned=2 GROUP BY Client

编辑:

当前结果集:

Client   | ReadyRecords  |  Outstanding  |  DueDate

Test     |     42        |      54       |   NULL
Stack    |     150       |      10       |   NULL
JBloggs  |     32        |      28       |   Yes
DBloggs  |     2         |      17       |   Yes
Overflow |     1         |      1        |   No

所需的结果集:

Client   | ReadyRecords  |  Outstanding  |  DueDate

Test     |     42        |      54       |   No
Stack    |     150       |      10       |   No
JBloggs  |     32        |      28       |   Yes
DBloggs  |     2         |      17       |   Yes
Overflow |     1         |      1        |   No

表 1:

id      |  Client   |   Actioned  | etc...

5245    |  Test     |      8      | etc...
....so on

表 2:

id   |   Client   |   DueDate

1    |  JBloggs   | 2012-12-01 00:00:00.000
2    |  DBloggs   | 2012-12-05 00:00:00.000
3    |  Overflow  | 2012-12-12 00:00:00.000

如果您还需要什么,请告诉我。

类似/相关问题:

【问题讨论】:

  • 还应该使用 count(1) 而不是 count(*),这与 count(*) 的工作方式相同,但执行速度比获取 *(all) 值要快得多...
  • @MayankPathak 谢谢你,我将从现在开始使用它。
  • @MayankPathak 我不确定 SQL Server 中的 count(*) 和 count(1) 之间是否存在任何性能差异。见this answer

标签: sql sql-server sql-server-2008-r2


【解决方案1】:

您需要将ISNULL()COALESCE() 函数应用于整个内联子查询,如下所示:

SELECT 
    Client, 
    COUNT(*) AS ReadyRecords, 
    (SELECT COUNT(*) FROM Table1 EPR 
     WHERE actioned=8 AND EPR.Client=Table1.Client
    ) AS Outstanding, 

    COALESCE(
        (SELECT TOP 1 
            CASE 
                WHEN DueDate < GETDATE() THEN 'Yes' 
            END AS DueDate
        FROM Table2 GL WHERE GL.Client=Table1.Client ORDER BY DueDate
        ), 'No' 
    ) AS DueDate

FROM Table1  WHERE Actioned=2  GROUP BY Client ;

或将CASE 表达式移到那里:

SELECT 
    Client, 
    COUNT(*) AS ReadyRecords, 
    (SELECT COUNT(*) FROM Table1 EPR 
     WHERE actioned=8 AND EPR.Client=Table1.Client
    ) AS Outstanding, 

    CASE WHEN 
           (SELECT TOP 1 
              DueDate
            FROM Table2 GL WHERE GL.Client=Table1.Client ORDER BY DueDate
           ) < GETDATE() 
        THEN 'Yes'
        ELSE 'No'
    END AS DueDate

FROM Table1  WHERE Actioned=2  GROUP BY Client ;

【讨论】:

  • 这非常有效。我在我的项目中使用了 COALESCE 部分。谢谢。
【解决方案2】:

首先,你需要知道,表中的日期时间字段可能会显示为NULL,但是在查询中使用它时,sql将其转换为该数据类型允许的最小日期,即'1900-01 -01',因此您可能会得到比实际更多的“是”值。

【讨论】:

    【解决方案3】:
    You can use this...
    SELECT 
    Client, 
    COUNT(*) AS ReadyRecords, 
    (SELECT COUNT(*) FROM Table1 EPR WHERE actioned=8 AND EPR.Client=Table1.Client) AS Outstanding, 
    (SELECT TOP 1 
        CASE 
            WHEN DueDate < GETDATE() THEN 'Yes' 
            ELSE ISNULL(Cast(DueDate AS VARCHAR),'NO' )        
        END AS DueDate
    FROM Table2 GL WHERE GL.Client=Table1.Client ORDER BY DueDate) AS DueDate
    
    FROM Table1 WHERE Actioned=2 GROUP BY Client
    

    【讨论】:

    • 我试过你说的,但我仍然在结果集中得到'NULL'。我已经用 2 个表格和我现在得到的结果集(有和没有你的更改)和所需的结果集编辑了我的原始帖子。
    【解决方案4】:

    我认为问题在于,如果 DueDate 为 NULL,则您的 DueDate &lt; GetDate() 结果为 NULL,并且您得到 No 作为结果,因为在这种情况下,DueDate 永远不会小于 GetDate。像这样改变顺序

    CASE 
        WHEN DueDate IS NULL THEN 'No'
        WHEN DueDate < GETDATE() THEN 'Yes'        
    ELSE 'No' 
    END AS DueDate
    

    通过这样做,在其他条件之前首先检查 NULL 值。或者,您可以将此行更改为

    WHEN ISNULL(DueDate,'Some Valid Default Value Here') < GETDATE() THEN 'Yes'    
    

    【讨论】:

      【解决方案5】:

      这项工作是否有效 - 怀疑其中可能存在一些故障,但我目前没有管理 sudio:

      SELECT 
              Client, 
              COUNT(*) AS ReadyRecords, 
              (SELECT COUNT(*) FROM Table1 EPR WHERE actioned=8 AND EPR.Client=Table1.Client) AS Outstanding, 
              [DueDate] = CASE 
                                      WHEN [MXDATE] < GETDATE() THEN 'Yes' 
                                      WHEN [MXDATE] IS NULL THEN 'No' 
                                  ELSE 'No' 
                                  END 
      FROM 
          Table1 T1
          LEFT OUTER JOIN
              (
              SELECT 
                  Client,
                  [MXDATE] = MAX(DueDate)
              FROM Table2
                  GROUP BY Client
              ) GL
              ON
               GL.Client=T1.Client 
      WHERE Actioned=2 
      GROUP BY Client
      

      【讨论】:

      • 对我来说似乎没有,我在执行您的解决方案时遇到此错误:消息 8120,级别 16,状态 1,第 15 行列“客户”在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句。
      • 不用担心:您有解决方案,但我添加了缺少的 GROUP BYanyway
      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 2014-04-04
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多