我正在尝试编写T-sql脚本,它将找到一个表的“打开”记录
数据结构如下
Id (int PK) Ts (datetime) Art_id (int) Amount (float)
1 '2009-01-01' 1 1
2 '2009-01-05' 1 -1
3 '2009-01-10' 1 1
4 '2009-01-11' 1 -1
5 '2009-01-13' 1 1
6 '2009-01-14' 1 1
7 '2009-01-15' 2 1
8 '2009-01-17' 2 -1
9 '2009-01-18' 2 1
根据我的需要,我试图仅显示每一篇文章的最后一笔之后的记录,其中0按最后一次运行的零值的日期排序。所以我试图抽象(显示)Art_id = 1的记录5和6以及art_id = 2的记录9。我正在使用MSSQL2005,我的表有大约30K的记录,有6000个不同的ART_ID值。
答案 0 :(得分:2)
在这个解决方案中,我只想找到不是的所有行,其中Art_id的后续行,其中运行总和为0.我假设我们可以使用该ID作为更好的决胜局而不是TS,因为两行可以使用相同的时间戳进入,但它们将获得顺序标识值。
;WITH base AS
(
SELECT
ID, Art_id, TS, Amount,
RunningSum = Amount + COALESCE
(
(
SELECT SUM(Amount)
FROM dbo.foo
WHERE Art_id = f.Art_id
AND ID < f.ID
)
, 0
)
FROM dbo.[table name] AS f
)
SELECT ID, Art_id, TS, Amount
FROM base AS b1
WHERE NOT EXISTS
(
SELECT 1
FROM base AS b2
WHERE Art_id = b1.Art_id
AND ID >= b1.ID
AND RunningSum = 0
)
ORDER BY ID;
答案 1 :(得分:1)
完整的工作查询:
SELECT
*
FROM TABLE_NAME E
JOIN
(SELECT
C.ART_ID,
MAX(TS) MAX_TS
FROM
(SELECT
ART_ID,
TS,
COALESCE((SELECT SUM(AMOUNT) FROM TABLE_NAME B WHERE (B.Art_id = A.Art_id) AND (B.Ts < A.Ts)),0) ROW_SUM
FROM TABLE_NAME A) C
WHERE C.ROW_SUM = 0
GROUP BY C.ART_ID) D
ON
(D.ART_ID = E.ART_ID) AND
(E.TS >= D.MAX_TS)
首先我们计算每一行的运行总和:
SELECT
ART_ID,
TS,
COALESCE((SELECT SUM(AMOUNT) FROM TABLE_NAME B WHERE (B.Art_id = A.Art_id) AND (B.Ts < A.Ts)),0) ROW_SUM
FROM TABLE_NAME A
然后我们用0:
寻找上一篇文章SELECT
C.ART_ID,
MAX(TS) MAX_TS
FROM
(SELECT
ART_ID,
TS,
COALESCE((SELECT SUM(AMOUNT) FROM TABLE_NAME B WHERE (B.Art_id = A.Art_id) AND (B.Ts < A.Ts)),0) ROW_SUM
FROM TABLE_NAME A) C
WHERE C.ROW_SUM = 0
GROUP BY C.ART_ID
答案 2 :(得分:1)
您可以找到运行总和为零的所有行:
select cur.id, cur.art_id
from @articles cur
left join @articles prev
on prev.art_id = cur.art_id
and prev.id <= cur.id
group by cur.id, cur.art_id
having sum(prev.amount) = 0
然后,您可以使用零运行总和查询行之后的所有行:
select a.*
from @articles a
left join (
select cur.id, cur.art_id, running = sum(prev.amount)
from @articles cur
left join @articles prev
on prev.art_id = cur.art_id
and prev.ts <= cur.ts
group by cur.id, cur.art_id
having sum(prev.amount) = 0
) later_zero_running on
a.art_id = later_zero_running.art_id
and a.id <= later_zero_running.id
where later_zero_running.id is null
LEFT JOIN与WHERE结合使用:在此行之后不能有一行,其中运行总和为零。