2014-07-13 2 views
0

내가 가진 테이블 판매 항목 각각에 속하는된다 = 'C'송장 및 CAT없이 바로 아래 행은 = 'C'CAT와 SQL 서버 : 쿼리 순차적 자식 행

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

아래 행 등 송장.

것은, 내가 쿼리 다음을 사용 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'입니까? SQL 서버에서

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

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 
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'