2014-07-13 53 views
0

我有一个表像下面的SQL Server:查询顺序子行

╔══════════════════════════════════╗ 
║ 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 

结果

╔════════╦═════════╦═══════╦═══════════╦═════════╦════════╗ 
║ 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 ║ 
╚══════════╩══════════════╩══════╩════════════╩═════════╩════════╝ 
+1

SQL-Server上的哪个版本? 2012年,2008年,2005年?你有没有选择重构你的数据库设计? *(这种结构不适合您使用的用例。)* – MatBailie

+0

MSSQL 2008.不,我没有重构选项。它被解析并从平坦表格报告中导入。 – lukeskywacko

回答

0

在SQL Server 2005中有只用于窗的聚合函数的支持有限,所以这种混合的老风格的语法加分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 
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'