Sql案例查询时

时间:2013-06-11 08:15:23

标签: sql sql-server sql-server-2008 tsql select

我发现“CASE WHEN”语句对我的查询非常有用。 但这是我的查询(仅选择):

SELECT  dbo.ARCHIVE.SYSTEM_KEY AS PROTOCOLLO, 
        CASE dbo.ARCHIVEDEST.ERR_ID WHEN 0 THEN 'OK' ELSE 'KO' END AS ESITO, 
        CASE WHEN dbo.ARCHIVEDEST.XMODE IN ('R', 'K', 'H') THEN 'RX' ELSE 'TX' END AS 'T/R', 
        CASE 'T/R' WHEN 'TX' THEN CONTACTORIGIN.address ELSE CONTACTDESTINATION.address END AS Utente, 

问题出现在第三个Case语句中,因为不评估先前的'T / R'查询(对于所有记录,它返回'CONTACTORIGIN.address'。 有可能这样做吗?或者我的方式错了?

4 个答案:

答案 0 :(得分:0)

你必须重复测试:

SELECT  dbo.ARCHIVE.SYSTEM_KEY AS PROTOCOLLO, 
        CASE dbo.ARCHIVEDEST.ERR_ID WHEN 0 THEN 'OK' ELSE 'KO' END AS ESITO, 
        CASE WHEN dbo.ARCHIVEDEST.XMODE IN ('R', 'K', 'H') THEN 'RX' ELSE 'TX' END AS 'T/R', 
        CASE CASE WHEN dbo.ARCHIVEDEST.XMODE NOT IN ('R', 'K', 'H') THEN CONTACTORIGIN.address ELSE CONTACTDESTINATION.address END AS Utente, 

或者您可以制作子查询:

SELECT PROTOCOLLO, ESITO, [T/R],
    CASE WHEN [T/R] = 'TX' THEN CONTACTORIGIN.address ELSE CONTACTDESTINATION.address END AS Utente
FROM
(SELECT  dbo.ARCHIVE.SYSTEM_KEY AS PROTOCOLLO, 
        CASE dbo.ARCHIVEDEST.ERR_ID WHEN 0 THEN 'OK' ELSE 'KO' END AS ESITO, 
        CASE WHEN dbo.ARCHIVEDEST.XMODE IN ('R', 'K', 'H') THEN 'RX' ELSE 'TX' END AS [T/R], 
) s

答案 1 :(得分:0)

如果您不想重复您的案例陈述,您有两种选择,第一种是将其中一种移至子查询,即

SELECT  PROTOCOLLO,
        ESITO,
        [T/R],
        CASE [T/R] WHEN 'TX' THEN CONTACTORIGIN.address ELSE CONTACTDESTINATION.address END AS Utente
FROM    (   SELECT  dbo.ARCHIVE.SYSTEM_KEY AS PROTOCOLLO, 
                    CASE dbo.ARCHIVEDEST.ERR_ID WHEN 0 THEN 'OK' ELSE 'KO' END AS ESITO, 
                    CASE WHEN dbo.ARCHIVEDEST.XMODE IN ('R', 'K', 'H') THEN 'RX' ELSE 'TX' END AS 'T/R'
            FROM    ....
        ) SubQuery

或者您可以在CROSS APPLY

中移动CASE声明
SELECT  dbo.ARCHIVE.SYSTEM_KEY AS PROTOCOLLO, 
        CASE dbo.ARCHIVEDEST.ERR_ID WHEN 0 THEN 'OK' ELSE 'KO' END AS ESITO, 
        'T/R', 
        CASE [T/R] WHEN 'TX' THEN CONTACTORIGIN.address ELSE CONTACTDESTINATION.address END AS Utente
FROM    ...
        CROSS APPLY
        (   SELECT  CASE WHEN dbo.ARCHIVEDEST.XMODE IN ('R', 'K', 'H') THEN 'RX' ELSE 'TX' END AS 'T/R'
        ) tx

答案 2 :(得分:0)

使用子查询定义T/R别名;

SELECT  *
,       CASE 'T/R' WHEN 'TX' THEN CONTACTORIGIN.address ELSE CONTACTDESTINATION.address 
            END AS Utente
FROM    (
        SELECT  CASE dbo.ARCHIVEDEST.ERR_ID WHEN 0 THEN 'OK' ELSE 'KO' END AS ESITO
        ,       CASE WHEN dbo.ARCHIVEDEST.XMODE IN ('R', 'K', 'H') THEN 'RX' ELSE 'TX' 
                    END AS 'T/R'
        FROM    dbo.ARCHIVE.SYSTEM_KEY AS PROTOCOLLO
        ) as SubQueryAlias

答案 3 :(得分:0)

当您在SELECT子句中计算列的值时,不允许您访问在同一SELECT子句中计算的任何其他计算值 - 因为(根据SQL标准) )并行计算列(它们可能不是,但假设某些实现执行此操作),因此计算值尚不可用。

您可以将“早期”计算放在子查询或CTE中:

SELECT *,
    CASE [T/R] WHEN 'TX' THEN CONTACTORIGIN.address ELSE CONTACTDESTINATION.address END AS Utente
FROM (
    SELECT  dbo.ARCHIVE.SYSTEM_KEY AS PROTOCOLLO, 
        CASE dbo.ARCHIVEDEST.ERR_ID WHEN 0 THEN 'OK' ELSE 'KO' END AS ESITO, 
        CASE WHEN dbo.ARCHIVEDEST.XMODE IN ('R', 'K', 'H') THEN 'RX' ELSE 'TX' END AS [T/R], 

    ...
) t