我有这个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)c列值是从查询行12-16获得的。然后在表格第3行(表格第3行有U和与表格第2行相同的N)中,从绝对值中获取c的值:
来自Total(第2行)-Cr(第2行)的。换句话说,从ABS(Tpa)获得的C列,其先前具有U和相同的N(U和N的组)。
C柱是从ABS(Tpa)获得的,其先前具有U和相同的N(U和N的组)。
列Tpa中的值从列Total-Cr获得。 如果Total-Cr> 0,则Tpa = 0且R = Total-Cr但如果Total-Cr <= 0,则Tpa = Total-Cr且R列为R = 0.
表格行5和6中的R值是Total-Cr的结果。如果表行是表中的最后一行(按U和N分组),则会出现这种情况。
答案 0 :(得分:0)
根据我的理解,这种类型的任务可以通过LAG / LEAD等分析函数轻松解决,并使用SUM(...)计算运行总计(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
根据需要生成准确的结果。