[英]SQL Server query : how to use left outer join
我有這個SQL查詢:
SELECT
COALESCE(a.U, '') AS U,
COALESCE(a.N, '') AS N,
COALESCE (a.J, '')AS J,
DATENAME(mm, a.P) AS Month,
DATENAME(yyyy, a.P) AS Year,
COALESCE(SUM(a.T), 0) AS Total,
COALESCE(SUM(b.Pa), 0) AS Cr,
COALESCE(SUM(a.T), 0) - COALESCE(SUM(b.Pa), 0) AS TPa
FROM
t1 AS a
LEFT OUTER JOIN
(SELECT
U, N, SUM(Cr)
FROM
t2
WHERE
U IS NOT NUll AND N IS NOT NULL
GROUP BY
U, N) AS b ON a.U = b.U AND a.N = b.N
WHERE
a.L IS NOT NULL
GROUP BY
a.U, a.N, a.J,
DATENAME(mm, a.P), DATENAME(yyyy, a.P)
ORDER BY
Month, Year DESC
該查詢將產生以下輸出:
+----+-------+---+--------+-------+---------+------+--------+
| U | N | J | Month | Year | Total | Cr | Tpa |
+----+-------+---+--------+-------+---------+------+--------+
| 2B | Mark | a | April | 2016 | 1500 | 0 | 1500 |
| 2D | Jhon | b | April | 2016 | 100 | 4300 | -4200 |
| 2D | Jhon | a | April | 2016 | 2000 | 4300 | -2300 |
| 3A | Van | a | April | 2016 | 1500 | 7000 | -5500 |
| 2D | Jhon | a | May | 2016 | 500 | 4300 | -3800 |
| 3A | Van | a | May | 2016 | 1200 | 7000 | -5800 |
+----+-------+---+--------+-------+---------+------+--------+
如果我想生成此輸出,如何進行SQL查詢:
+----+-------+---+--------+-------+---------+------+--------+-------+
| U | N | J | Month | Year | Total | Cr | Tpa | R |
+----+-------+---+--------+-------+---------+------+--------+-------+
| 2B | Mark | a | April | 2016 | 1500 | 0 | 0 | 1500 |
| 2D | Jhon | b | April | 2016 | 100 | 4300 | -4200 | 0 |
| 2D | Jhon | a | April | 2016 | 2000 | 4200 | -2200 | 0 |
| 3A | Van | a | April | 2016 | 1500 | 7000 | -5500 | 0 |
| 2D | Jhon | a | May | 2016 | 500 | 2200 | -1700 | -1700 |
| 3A | Van | a | May | 2016 | 1200 | 5500 | -4300 | -4300 |
+----+-------+---+--------+-------+---------+------+--------+-------+
首先,(從表行1,2,4集中)從查詢行12-16獲得c列值。 然后在表第3行中(表第3行的U和表第2行的N相同),從絕對值獲得c的值:
來自Total(第2行)-Cr(第2行)。 換句話說,列C是從以前具有U和相同N(由U和N分組)的ABS(Tpa)獲得的。
C柱是從以前具有U和相同N(由U和N分組)的ABS(Tpa)獲得的。
Tpa列中的值是從Total-Cr列中獲得的。 如果Total-Cr> 0,則Tpa = 0且R = Total-Cr,但如果Total-Cr <= 0,則Tpa = Total-Cr且列R = 0。
表第5和6行中的R值是Total-Cr的結果。 如果表行是表中的最后一行(按U和N分組),則會發生這種情況。
根據我的理解,可以使用諸如LAG / LEAD之類的分析功能並通過SUM(...)over(PARTITION BY ... ORDER BY ...)來計算運行總計,輕松解決此類任務。
不幸的是,這些選項僅從SQL Server 2012開始可用。因此,我嘗試進行更復雜的查詢,但該查詢甚至應在較早版本上運行(於2008年嘗試)。
這是查詢。
我在公用表表達式(CTE)t1,t2中生成了值。
T3主要模仿您的查詢。 只需添加row_number()即可唯一地標識組中的行,還可以查找組中的最后一條記錄。
最后,t4有新的計算。
with
t1 as
(
select '2B' as U, 'Mark' as N, 'a' as J, '2016-04-01' as P, 1500 as T, 1 as L union all
select '2D' as U, 'Jhon' as N, 'b' as J, '2016-04-01' as P, 100 as T, 1 as L union all
select '2D' as U, 'Jhon' as N, 'a' as J, '2016-04-04' as P, 2000 as T, 1 as L union all
select '2D' as U, 'Jhon' as N, 'a' as J, '2016-05-05' as P, 500 as T, 1 as L union all
select '3A' as U, 'Van' as N, 'a' as J, '2016-04-05' as P, 1500 as T, 1 as L union all
select '3A' as U, 'Van' as N, 'a' as J, '2016-05-05' as P, 1200 as T, 1 as L
),
t2 as
(
select '2B' as U,'Mark' as N, 0 as Cr union all
select '2D' as U,'Jhon' as N, 4300 as Cr union all
select '3A' as U,'Van' as N, 7000 as Cr
),
t3 as
(
SELECT
COALESCE(a.U, '') AS U,
COALESCE(a.N, '') AS N,
COALESCE (a.J, '')AS J,
DATENAME(mm, a.P) AS Month,
DATENAME(yyyy, a.P) AS Year,
COALESCE(SUM(a.T), 0) AS Total,
COALESCE(SUM(b.Pa), 0) AS Cr,
--COALESCE(SUM(a.T), 0) - COALESCE(SUM(b.Pa), 0) AS TPa,
row_number() over (partition by a.U, a.N order by J desc, DATENAME(mm, a.P)) rn,
row_number() over (partition by a.U, a.N order by J , DATENAME(mm, a.P) desc) rn_last
FROM
t1 AS a
LEFT OUTER JOIN
(SELECT
U, N, SUM(Cr) as Pa
FROM
t2
WHERE
U IS NOT NUll AND N IS NOT NULL
GROUP BY
U, N) AS b ON a.U = b.U AND a.N = b.N
WHERE
a.L IS NOT NULL
GROUP BY
a.U, a.N, a.J,
DATENAME(mm, a.P), DATENAME(yyyy, a.P)
)
,t4 as (
select cte1.*
,sum(cte2.Total) Cum_Total -- running total
,cte1.Cr - sum(cte2.Total) as Cr_Next
from t3 cte1
inner join t3 cte2 on cte1.U = cte2.U and cte1.N = cte2.N and cte1.rn >= cte2.rn
group by
cte1.U, cte1.N, cte1.J, cte1.Month, cte1.Year, cte1.Total, cte1.Cr, cte1.rn, cte1.rn_last
)
select U,N,J,Month,Year,Total,Cr_New as Cr,
case when Total - Cr_New > 0 then 0 else Total - Cr_New end as Tpa,
case when rn_last = 1 then Total - Cr_New else 0 end R
from
(
select cte1.*
, case when cte1.rn =1 then cte1.Cr else cte2.Cr_Next end as Cr_New
from t4 as cte1
left join t4 cte2 on cte1.U = cte2.U and cte1.N = cte2.N and cte1.rn = cte2.rn +1
) t
order by 1,2,3 desc
它產生所需的准確結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.