SQL子查询CASE

时间:2014-09-16 16:04:16

标签: sql sql-server

SELECT 
  ac.ac_code,    
  (SELECT CASE
              WHEN SUM(L.l_valuedr) - SUM(L.l_valuecr) >= 0 THEN SUM(L.l_valuedr) - SUM(L.l_valuecr)
              ELSE 0
          END AS dr,
          CASE
              WHEN SUM(L.l_valuedr) - SUM(L.l_valuecr) < 0 THEN SUM(L.l_valuecr) - SUM(L.l_valuedr)
              ELSE 0
          END AS cr
   FROM Ledger AS L
   WHERE (l_date < '09/08/2014')
     AND (l_accode = ac.ac_code)
  ) AS bf,
  CASE
    WHEN SUM(Ledger_2.l_valuedr) - SUM(Ledger_2.l_valuecr) >= 0 THEN SUM(Ledger_2.l_valuedr) - SUM(Ledger_2.l_valuecr)
    ELSE 0
  END AS dr,
  CASE
    WHEN SUM(Ledger_2.l_valuedr) - SUM(Ledger_2.l_valuecr) < 0 THEN SUM(Ledger_2.l_valuecr) - SUM(Ledger_2.l_valuedr)
    ELSE 0
  END AS cr
FROM Ac_Accounts AS ac
INNER JOIN Ac_Costelements ON ac.ac_costelement = Ac_Costelements.ce_code
INNER JOIN Ledger AS Ledger_2 ON ac.ac_code = Ledger_2.l_accode
WHERE (Ledger_2.l_date >= '09/08/2014')
  AND (Ledger_2.l_date <= '09/15/2014')
  AND (Ledger_2.l_accode = ac.ac_code)
GROUP BY ac.ac_code

显示此错误:

  

Msg 116,Level 16,State 1,Line 5
  当未使用EXISTS引入子查询时,只能在选择列表中指定一个表达式。

2 个答案:

答案 0 :(得分:1)

我认为您可以按如下方式简化查询:

WITH CTE AS
(   SELECT  ac.ac_code,
            Value1 = SUM(CASE WHEN l.l_date < '20140908' THEN l.l_valuedr - l.l_valuecr ELSE 0 END),
            Value2 = SUM(CASE WHEN l.l_date >= '20140908' THEN l.l_valuedr - l.l_valuecr ELSE 0 END)
    FROM    Ac_Accounts AS ac
            INNER JOIN Ac_Costelements AS c
                ON ac.ac_costelement = c.ce_code
            INNER JOIN Ledger AS l 
                ON ac.ac_code = l.l_accode
    WHERE   l.l_date <= '20140915'
    GROUP BY ac.ac_code
)
SELECT  ac_code,
        dr = CASE WHEN Value1 >= 0 THEN Value1 END,
        cr = CASE WHEN Value1 < 0 THEN Value1 * -1 END,
        dr = CASE WHEN Value1 >= 0 THEN Value2 END,
        cr = CASE WHEN Value1 < 0 THEN Value2 * -1 END
FROM    CTE;

不是使用相关子查询来获取给定日期之前的金额,而是在主查询中获取该日期之后的金额,您可以使用SUM中的CASE在同一查询中获取这两个金额。

然后通过将一些逻辑移动到子查询,您可以通过减少已完成的总数来简化查询。

答案 1 :(得分:0)

为什么不把它们一起移动呢? 从这里开始:

(SELECT CASE
              WHEN SUM(L.l_valuedr) - SUM(L.l_valuecr) >= 0 THEN SUM(L.l_valuedr) - SUM(L.l_valuecr)
              ELSE 0
          END AS dr,
          CASE
              WHEN SUM(L.l_valuedr) - SUM(L.l_valuecr) < 0 THEN SUM(L.l_valuecr) - SUM(L.l_valuedr)
              ELSE 0
          END AS cr
   FROM Ledger AS L
   WHERE (l_date < '09/08/2014')
     AND (l_accode = ac.ac_code)) AS bf

对于这样的事情:

(SELECT CASE
         WHEN SUM(L.l_valuedr) - SUM(L.l_valuecr) >= 0 
         THEN SUM(L.l_valuedr) - SUM(L.l_valuecr)
         ELSE SUM(L.l_valuecr) - SUM(L.l_valuedr)
        END AS newcolumn
   FROM Ledger AS L
   WHERE (l_date < '09/08/2014')
     AND (l_accode = ac.ac_code)) AS bf
相关问题