我有一张如下表格
╔══════════════════════════════════╗
║ id ACCT CAT AMT MYDATE ║
╠══════════════════════════════════╣
║ 1 1111 c 200 6/1/2014 ║
║ 2 2121 100 6/1/2014 ║
║ 3 3131 100 6/1/2014 ║
║ 4 2222 c 250 6/2/2014 ║
║ 5 3131 100 6/2/2014 ║
║ 6 2121 100 6/2/2014 ║
║ 7 4141 50 6/2/2014 ║
║ 8 1111 c 350 6/3/2014 ║
║ 9 5151 150 6/3/2014 ║
║ 10 6161 200 6/3/2014 ║
║ 11 3333 c 400 6/3/2014 ║
║ 12 2121 200 6/3/2014 ║
║ 13 3131 200 6/3/2014 ║
║ 14 1111 c 500 6/5/2014 ║
║ 15 4141 100 6/5/2014 ║
║ 16 5151 200 6/5/2014 ║
║ 17 6161 200 6/5/2014 ║
║ 18 2222 c 400 6/5/2014 ║
║ 19 4141 400 6/5/2014 ║
╚══════════════════════════════════╝
CAT ='c'的行是发票,右下方没有CAT ='c'的行是属于每张发票的已售商品。
获取id = 14的项目,我使用以下查询
WITH tbl (id, ACCT, CAT, AMT, MYDATE)
AS
(
SELECT 1, 1111, 'c', 200, '6/1/2014'
UNION ALL SELECT 2, 2121, ' ', 100, '6/1/2014'
UNION ALL SELECT 3, 3131, ' ', 100, '6/1/2014'
UNION ALL SELECT 4, 2222, 'c', 250, '6/2/2014'
UNION ALL SELECT 5, 3131, ' ', 100, '6/2/2014'
UNION ALL SELECT 6, 2121, ' ', 100, '6/2/2014'
UNION ALL SELECT 7, 4141, ' ', 50, '6/2/2014'
UNION ALL SELECT 8, 1111, 'c', 350, '6/3/2014'
UNION ALL SELECT 9, 5151, ' ', 150, '6/3/2014'
UNION ALL SELECT 10, 6161, ' ', 200, '6/3/2014'
UNION ALL SELECT 11, 3333, 'c', 400, '6/3/2014'
UNION ALL SELECT 12, 2121, ' ', 200, '6/3/2014'
UNION ALL SELECT 13, 3131, ' ', 200, '6/3/2014'
UNION ALL SELECT 14, 1111, 'c', 500, '6/5/2014'
UNION ALL SELECT 15, 4141, ' ', 100, '6/5/2014'
UNION ALL SELECT 16, 5151, ' ', 200, '6/5/2014'
UNION ALL SELECT 17, 6161, ' ', 200, '6/5/2014'
UNION ALL SELECT 18, 2222, 'c', 400, '6/5/2014'
UNION ALL SELECT 19, 4141, ' ', 400, '6/5/2014'
)
, tid( orgid )
AS
(
SELECT TOP (1) id FROM tbl WHERE MYDATE = '6/5/2014' and ACCT = 1111 and AMT = 500
)
SELECT * from tbl
INNER JOIN tid on tbl.id > tid.orgid
INNER JOIN (SELECT ISNULL ( MIN ( id ), (SELECT MAX ( id ) + 1 from tbl ) ) AS nextnid FROM tbl
WHERE id > ( SELECT id from tid ) AND CAT = 'c' ) as t2 on tbl.id < t2.nextnidid < t2.nextnid
RESULT
╔════════╦═════════╦═══════╦═══════════╦═════════╦════════╗
║ id ║ ACCT ║ AMT ║ MYDATE ║ orgid ║ nextid ║
╠════════╬═════════╬═══════╬═══════════╬═════════╬════════╣
║ 15 ║ 4141 ║ 100 ║ 6/5/2014 ║ 14 ║ 18 ║
║ 16 ║ 5151 ║ 200 ║ 6/5/2014 ║ 14 ║ 18 ║
║ 17 ║ 6161 ║ 200 ║ 6/5/2014 ║ 14 ║ 18 ║
╚════════╩═════════╩═══════╩═══════════╩═════════╩════════╝
现在,我的问题是..如何查询ACCT = 1111和CREDIT ='c'的所有子项目行?
Result should be something like this
╔══════════╦══════════════╦══════╦════════════╦═════════╦════════╗
║ id ║ ACCT ║ AMT ║ MYDATE ║ orgid ║ nextid ║
╠══════════╬══════════════╬══════╬════════════╬═════════╬════════╣
║ 2 ║ 2121 ║ 100 ║ 6/1/2014 ║ 1 ║ 4 ║
║ 3 ║ 3131 ║ 100 ║ 6/1/2014 ║ 1 ║ 4 ║
║ 9 ║ 5151 ║ 150 ║ 6/3/2014 ║ 8 ║ 11 ║
║ 10 ║ 6161 ║ 200 ║ 6/3/2014 ║ 8 ║ 11 ║
║ 15 ║ 4141 ║ 100 ║ 6/5/2014 ║ 14 ║ 18 ║
║ 16 ║ 5151 ║ 200 ║ 6/5/2014 ║ 14 ║ 18 ║
║ 17 ║ 6161 ║ 200 ║ 6/5/2014 ║ 14 ║ 18 ║
╚══════════╩══════════════╩══════╩════════════╩═════════╩════════╝
答案 0 :(得分:0)
在SQL Server 2005中,只有有限的窗口聚合函数支持,所以这混合了旧式语法加上MIN OVER:
WITH tbl (id, ACCT, CAT, AMT, MYDATE)
AS
(
SELECT 1, 1111, 'c', 200, '6/1/2014'
UNION ALL SELECT 2, 2121, ' ', 100, '6/1/2014'
UNION ALL SELECT 3, 3131, ' ', 100, '6/1/2014'
UNION ALL SELECT 4, 2222, 'c', 250, '6/2/2014'
UNION ALL SELECT 5, 3131, ' ', 100, '6/2/2014'
UNION ALL SELECT 6, 2121, ' ', 100, '6/2/2014'
UNION ALL SELECT 7, 4141, ' ', 50, '6/2/2014'
UNION ALL SELECT 8, 1111, 'c', 350, '6/3/2014'
UNION ALL SELECT 9, 5151, ' ', 150, '6/3/2014'
UNION ALL SELECT 10, 6161, ' ', 200, '6/3/2014'
UNION ALL SELECT 11, 3333, 'c', 400, '6/3/2014'
UNION ALL SELECT 12, 2121, ' ', 200, '6/3/2014'
UNION ALL SELECT 13, 3131, ' ', 200, '6/3/2014'
UNION ALL SELECT 14, 1111, 'c', 500, '6/5/2014'
UNION ALL SELECT 15, 4141, ' ', 100, '6/5/2014'
UNION ALL SELECT 16, 5151, ' ', 200, '6/5/2014'
UNION ALL SELECT 17, 6161, ' ', 200, '6/5/2014'
UNION ALL SELECT 18, 2222, 'c', 400, '6/5/2014'
UNION ALL SELECT 19, 4141, ' ', 400, '6/5/2014'
)
,cte1 as
(
select
t1.*,
-- find the id of the next invoice id
-- all rows for an invoice share the same id
( select min(t2.id)
from tbl as t2
where t2.id > t1.id
and CAT = 'c') as nextId
from tbl as t1
)
,cte2 as
(
select
cte1.*,
-- assign original invoice id/acct to each item
min(case when CAT = 'c' then id end) over (partition by nextId) as orgId,
min(case when CAT = 'c' then acct end) over (partition by nextId) as orgAcct
from cte1
)
select *
from cte2
where orgAcct = 1111
and id <> orgId
答案 1 :(得分:0)
JFYI,我在另一个论坛上问道,发现这个有点儿比较快
WITH tbl(id, ACCT, CAT, AMT, D)
AS
(
SELECT 1, 1111, 'c', 200, '6/1/2014'
UNION ALL SELECT 2, 2121, ' ', 100, '6/1/2014'
UNION ALL SELECT 3, 3131, ' ', 100, '6/1/2014'
UNION ALL SELECT 4, 2222, 'c', 250, '6/2/2014'
UNION ALL SELECT 5, 3131, ' ', 100, '6/2/2014'
UNION ALL SELECT 6, 2121, ' ', 100, '6/2/2014'
UNION ALL SELECT 7, 4141, ' ', 50, '6/2/2014'
UNION ALL SELECT 8, 1111, 'c', 350, '6/3/2014'
UNION ALL SELECT 9, 5151, ' ', 150, '6/3/2014'
UNION ALL SELECT 10, 6161, ' ', 200, '6/3/2014'
UNION ALL SELECT 11, 3333, 'c', 400, '6/3/2014'
UNION ALL SELECT 12, 2121, ' ', 200, '6/3/2014'
UNION ALL SELECT 13, 3131, ' ', 200, '6/3/2014'
UNION ALL SELECT 14, 1111, 'c', 500, '6/5/2014'
UNION ALL SELECT 15, 4141, ' ', 100, '6/5/2014'
UNION ALL SELECT 16, 5151, ' ', 200, '6/5/2014'
UNION ALL SELECT 17, 6161, ' ', 200, '6/5/2014'
UNION ALL SELECT 18, 2222, 'c', 400, '6/5/2014'
UNION ALL SELECT 19, 4141, ' ', 400, '6/5/2014'
)
, cte1
AS
(
SELECT * , CASE WHEN CAT = 'C' THEN id ELSE ( SELECT MAX( id ) FROM tbl AS aa
WHERE CAT = 'C' AND aa.id < tbl.id ) END AS orgId
FROM tbl
)
SELECT cc.* FROM cte1 AS bb
INNER JOIN cte1 as cc ON bb.id = cc.orgId AND cc.CAT = ' '
WHERE bb.ACCT = 1111 AND bb.CAT = 'C'