Reputation: 1
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
Showing this Error:
Msg 116, Level 16, State 1, Line 5
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Upvotes: 0
Views: 85
Reputation: 69769
I think you can simplify your query as follows:
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;
Rather than using a correlated subquery to get the amounts before a given date, and get the amount after that date in the main query, you can get both amounts within the same query by using CASE
inside the SUM.
Then by moving some of the logic to a subquery you can simplify the query by reducing the number of sums done.
Upvotes: 1
Reputation: 296
Instead of doing two case statements, why not move them together? Go from this:
(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
To something like this:
(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
Upvotes: 0