【问题标题】:SQL Subquery CASESQL 子查询案例
【发布时间】:2014-11-10 11:34:38
【问题描述】:
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

显示此错误:

消息 116,第 16 级,状态 1,第 5 行
当子查询不使用 EXISTS 引入时,选择列表中只能指定一个表达式。

【问题讨论】:

  • 您的问题出在您的第二列。您有一个返回多个行和列的 select 语句
  • @paqogomez -- 以及不止一列,如错误消息所示。
  • 尝试使用APPLY 代替 SQL 子查询,它允许您选择多个列。这是一个示例CROSS APPLY Explained

标签: sql sql-server


【解决方案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 在同一查询中获取这两个金额,而不是使用相关子查询来获取给定日期之前的金额,并在主查询中获取该日期之后的金额。

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

【讨论】:

    【解决方案2】:

    与其做两个 case 语句,为什么不把它们一起移动呢? 从这里开始:

    (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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-04
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-20
      相关资源
      最近更新 更多