T-SQL - 清空CASE +选择

时间:2015-03-23 12:03:59

标签: sql tsql

我遇到一个查询问题。这项工作:

select coalesce(((SUM(ati.anDebit) - SUM(ati.ancredit))),0) + 
        (select coalesce((SUM(anDebit)),0)  
        from tHE_AcctTransItem where acLinkDoc = '15-390-000523' and     SUBSTRING(acDoc,4,3) in ('391', '3B0') 
        and SUBSTRING(acKey, 3, 3) = '420' and acSubject = 'Company' and acAcct = '1200')
from tHE_AcctTransItem ati inner join tHE_AcctTrans at 
on ati.acKey = at.acKey 
where at.acDocType in('4100', '4620', '4630', '4700', '4730') 
and acLinkDoc = '15-390-000523' and acAcct = '1200' 
and acSubject = 'Company'

为了我的目的,我需要把CASE,我写下来:

select case when acDocType <> '4730' then (coalesce(((SUM(ati.anDebit) - SUM(ati.ancredit))),0) + 
    (select coalesce((SUM(anDebit)),0)  
    from tHE_AcctTransItem where acLinkDoc = '15-390-000523' and SUBSTRING(acDoc,4,3) in ('391', '3B0') 
    and SUBSTRING(acKey, 3, 3) = '420' and acSubject = 'Company' and acAcct = '1200')) 
else  coalesce(((SUM(ati.anDebit) - SUM(ati.ancredit))),0) * -1 
end from tHE_AcctTransItem ati inner join tHE_AcctTrans at on ati.acKey = at.acKey where at.acDocType in('4100', '4620', '4630', '4700', '4730') and acLinkDoc = '15-390-000523' and acAcct = '1200' and acSubject = 'Company' group by acDocType

但我没有收到任何东西。

select ati.* from tHE_AcctTransItem ati inner join tHE_AcctTrans at on ati.acKey = at.acKey  where at.acDocType in('4100', '4620', '4630', '4700', '4730') and acLinkDoc = '15-390-000523' and acAcct = '1200' and acSubject = 'Company'

这不会返回任何行,我不知道如何在第一个查询中显示结果但是有大小写。 从此查询中,只有此选择包含一些数据:

(select coalesce((SUM(anDebit)),0)  
        from tHE_AcctTransItem where acLinkDoc = '15-390-000523' and     SUBSTRING(acDoc,4,3) in ('391', '3B0') 
        and SUBSTRING(acKey, 3, 3) = '420' and acSubject = 'Company' and acAcct = '1200')

当我提出案件时,这不是总结。

3 个答案:

答案 0 :(得分:1)

首先,你的SQL有很多额外的括号,而且随之而来的格式化也很难阅读和调试。

没有group by子句的查询的select子句中的聚合函数将返回空记录。

declare @t table (
    k nvarchar(50),
    val int
)

select sum(val), avg(val), min(val), max(val) from @t

上面的内容返回一行所有空值。这允许您将聚合包装在coalesce函数中,并使select子句中的子查询起作用。

但是,在查询中添加group by子句,您不再获得空行。

declare @t table (
    k nvarchar(50),
    val int
)

select sum(val), avg(val), min(val), max(val) from @t group by k

上面没有返回任何记录,因此select子句中的子查询不会运行。

您可以尝试以下内容。如果第一个查询没有返回任何记录,则第二个查询有机会。 (请注意,无论两个查询都运行,所以如果查询是数据密集型的,您可能希望找到另一种方法。)

select coalesce((
    select 
        case 
            when acDocType <> '4730' 
            then 
                SUM(ati.anDebit) - SUM(ati.ancredit) + 
                (
                    select
                        coalesce(SUM(anDebit),0)  
                    from 
                        tHE_AcctTransItem 
                    where 
                        acLinkDoc = '15-390-000523' 
                        and SUBSTRING(acDoc,4,3) in ('391', '3B0') 
                        and SUBSTRING(acKey, 3, 3) = '420' 
                        and acSubject = 'Company' 
                        and acAcct = '1200'
                ) 
            else 
                SUM(ati.anDebit) - SUM(ati.ancredit) * -1 
            end 
    from 
        tHE_AcctTransItem ati 
        inner join tHE_AcctTrans at on ati.acKey = at.acKey 
    where 
        at.acDocType in('4100', '4620', '4630', '4700', '4730') 
        and acLinkDoc = '15-390-000523' 
        and acAcct = '1200' 
        and acSubject = 'Company' 
    group by
        acDocType
),(
    select 
        coalesce(SUM(anDebit),0)
    from
        tHE_AcctTransItem
    where
        acLinkDoc = '15-390-000523' 
        and SUBSTRING(acDoc,4,3) in ('391', '3B0') 
        and SUBSTRING(acKey, 3, 3) = '420' 
        and acSubject = 'Company' 
        and acAcct = '1200'
))

答案 1 :(得分:0)

我最好的猜测是你的SELECT子句的子查询:

SELECT coalesce(SUM(anDebit), 0)
FROM tHE_AcctTransItem
WHERE acLinkDoc = '15-390-000523'
    AND SUBSTRING(acDoc, 4, 3) IN (
        '391',
        '3B0'
        )
    AND SUBSTRING(acKey, 3, 3) = '420'
    AND acSubject = 'Company'
    AND acAcct = '1200'

此处唯一的查询是返回数据。在第一个查询中,您会得到结果,因为此子查询会盲目地将数据返回到查询中。您可能从中获得一条记录,然后该单一金额构成整个查询中返回的全部金额。为了好玩,只需将此子查询与您的整个第一个查询结果进行比较。我敢打赌,他们会是一样的。

第二个查询,CASE语句失败,因为现在此子查询的结果仅限于在acDocType&lt;&gt;时返回'4730'。自您的查询:

select ati.* from tHE_AcctTransItem ati inner join tHE_AcctTrans at on ati.acKey = at.acKey  where at.acDocType in('4100', '4620', '4630', '4700', '4730') and acLinkDoc = '15-390-000523' and acAcct = '1200' and acSubject = 'Company'

没有返回任何内容,它表明你的JOIN是坏的,或者你的WHERE语句限制每一条记录。这是你的问题。我会花一些时间查看那些更简化的select语句返回的数据,但是从WHERE语句中删除了大部分内容。

答案 2 :(得分:0)

逻辑上,如果您的第一个查询返回结果而第三个查询没有,那么差异必然导致问题。请注意,第一个查询中的子查询与主要的from和where子句没有关联。试试这个查询。我会

SELECT  at.acDocType ,
        ati.acDoc ,
        ati.acKey ,
        SUM(COALESCE(ati.anDebit, 0)) ,
        SUM(COALESCE(ATI.anCredit, 0))
FROM    tHE_AcctTransItem ati
        LEFT OUTER JOIN tHE_AcctTrans at ON ati.acKey = at.acKey
WHERE   ( at.acDocType IN ( '4100', '4620', '4630', '4700', '4730' )
          OR ( SUBSTRING(ati.acDoc, 4, 3) IN ( '391', '3B0' )
               AND SUBSTRING(ati.acKey, 3, 3) = '420'
             )
        )
        AND ati.acLinkDoc = '15-390-000523'
        AND ati.acAcct = '1200'
        AND ati.acSubject = 'Company'
GROUP BY ALL at.acDocType ,
        ati.acDoc ,
        ati.acKey

我希望你会看到主查询中的一个连接创建的空结果。