当CASE表达式不返回行

时间:2018-01-25 11:13:00

标签: sql-server sql-server-2014

此代码返回固定列198,然后返回另一个CASE。此CASE可能会返回0行(因为数据库中还有0行TRL_ORIGQTY,所以它甚至没有评估过)

如果有行,结果是(与其他组织一起测试):

ORG     SumTotal
198      98.51

如果数据库中没有行,则结果不显示,但应该是:

ORG     SumTotal
198      NULL

或其他:

ORG     SumTotal
198      00001

这是完整的代码:

declare @startdate varchar(30);
declare @enddate varchar(30);
declare @count int;    

set @startdate = '2017-12-01'
set @enddate = '2018-01-01'    

select @count = COUNT(*)
from R5TRANSLINES
where TRL_TYPE = 'STTK' 
  and TRL_TRANS in (select TRA_CODE from R5TRANSACTIONS 
                    where TRA_FROMCODE in ('198') 
                      and TRA_STATUS in ('A') 
                      and TRA_DATE between @startdate and @enddate)

select distinct 
    '198' as 'ORG',
    (SUM(CASE
            WHEN (TRL_ORIGQTY = 0 AND TRL_ORIGQTY > 0) THEN 0
            WHEN ((TRL_ORIGQTY - TRL_QTY) = 0 AND TRL_ORIGQTY = 0) THEN 100
            WHEN ((TRL_ORIGQTY - TRL_QTY) > TRL_ORIGQTY) THEN ((TRL_ORIGQTY / (TRL_ORIGQTY - TRL_QTY)) * 100)
            ELSE (((TRL_ORIGQTY - TRL_QTY) / TRL_ORIGQTY) * 100)
         END) OVER ()/@count) AS 'SumTotal'
from 
    R5TRANSLINES
where 
    TRL_TYPE = 'STTK' 
    and TRL_TRANS in (select TRA_CODE from R5TRANSACTIONS 
                      where TRA_FROMCODE in ('198') 
                        and TRA_STATUS in ('A')  
                        and TRA_DATE between @startdate and @enddate)

尝试使用ISNULLNOT EXISTS,或者使用其他CASE = NULL,但都没有效果......没有返回任何行。

更新后的代码:

select distinct
    'ESREQ1' as 'ORG',
    CASE COUNT(*) 
       WHEN 0 THEN 0
       ELSE (SUM(CASE
                    WHEN (TRL_ORIGQTY = 0 AND TRL_ORIGQTY > 0) THEN 0
                    WHEN ((TRL_ORIGQTY - TRL_QTY) = 0 AND TRL_ORIGQTY = 0) THEN 100
                    WHEN ((TRL_ORIGQTY - TRL_QTY) > TRL_ORIGQTY) THEN ((TRL_ORIGQTY / (TRL_ORIGQTY - TRL_QTY)) * 100)
                    ELSE (((TRL_ORIGQTY - TRL_QTY) / TRL_ORIGQTY) * 100)
                 END) OVER ()/@count) 
    END AS 'SumTotal'
from 
    R5TRANSLINES
where 
    TRL_TYPE = 'STTK' 
    and TRL_TRANS in (select TRA_CODE from R5TRANSACTIONS 
                      where UPPER(TRA_DESC) like '%AUDITESREQ1%' 
                        and TRA_FROMCODE in ('138-05') 
                        and TRA_STATUS in ('A') 
                        and TRA_DATE between @startdate and @enddate)
group by 
    TRL_ORIGQTY, TRL_QTY

1 个答案:

答案 0 :(得分:1)

返回0行的原因是0行中的SUM将不返回任何行(因此没有数据集)。唯一的例外是使用COUNT;当没有行时返回0。

因此,您可以事先使用CASE表达COUNT(*),然后将SUM放入ELSE

SELECT '198' AS ORG, --DISTINCT achieves nothing here, so I have removed it.
       CASE COUNT(*) WHEN 0 THEN 0
                     ELSE ... --your SUM
       END AS SumTotal
FROM R5TRANSLINES ...

另外,请在编写SQL时考虑使用White Space。您的代码很难阅读完全缺少缩进。它让您的生活更轻松,其他任何人都需要阅读您的陈述。 (这就是为什么我没有重写你的查询,因为我花了更多时间格式化它而不是其他任何东西)。

编辑:基于OP的最新SQL:

SELECT 'ESREQ1' AS ORG,
       CASE COUNT(*) WHEN 0 THEN 0
                     ELSE SUM(CASE WHEN (TRL_ORIGQTY = 0 AND TRL_ORIGQTY > 0) THEN 0
                                   WHEN ((TRL_ORIGQTY - TRL_QTY) = 0 AND TRL_ORIGQTY = 0) THEN 100
                                   WHEN ((TRL_ORIGQTY - TRL_QTY) > TRL_ORIGQTY) THEN ((TRL_ORIGQTY / (TRL_ORIGQTY - TRL_QTY)) * 100)
                                   ELSE (((TRL_ORIGQTY - TRL_QTY) / TRL_ORIGQTY) * 100)
                              END) / @count
       END AS SumTotal
FROM R5TRANSLINES
WHERE TRL_TYPE ='STTK'
  AND TRL_TRANS IN (SELECT TRA_CODE
                    FROM R5TRANSACTIONS
                    WHERE UPPER(TRA_DESC) LIKE '%AUDITESREQ1%'
                      AND TRA_FROMCODE IN ('138-05') 
                      AND TRA_STATUS = 'A'
                      AND TRA_DATE BETWEEN @startdate AND @enddate);

请注意,这是未经测试的,因为我没有任何示例数据来运行此操作。如果仍然无效,请提供一些我们可以运行的DDL和耗材样品数据。

感谢。