2013-07-10 30 views
1

什麼是填充在基於以下邏輯最後的表的第三列中的乾淨的方式:加入一個表,其中值的值之間位於從連續行中的其他表

分配B.appears在「上部」記錄TABLE A如果B.id落在2個連續的A.id記錄之間。

TABLE A 

id   text 
----------- ------------------ 
422   a 
473   b 
526   c 
577   d 




TABLE B 

id   appears 
----------- ------------------ 
465   yes 
569   yes 




FINAL TABLE SHOULD SHOW: 

id   text    appears 
----------- ------------------ --------------------- 
422   a     yes 
473   b 
526   c     yes 
577   d 

回答

1

這是一個完整的工作示例,包含您的數據以及每個子查詢的輸出。你可以自由地使用表變量或臨時表在分開的語句中打破它:

SET NOCOUNT ON 
GO 

    DECLARE @A TABLE 
    (
     [ID] SMALLINT 
     ,[Text] CHAR(1) 
    ) 

    DECLARE @B TABLE 
    (
     [ID] SMALLINT 
     ,[Text] CHAR(3) 
    ) 

    INSERT INTO @A ([ID], [Text]) 
    VALUES (422,'a') 
      ,(473,'b') 
      ,(526,'c') 
      ,(577,'d') 

    INSERT INTO @B ([ID], [Text]) 
    VALUES (465,'yes') 
      ,(569,'yes') 

    ;WITH DataSource ([RowID], [ID], [Text]) AS 
    ( -- Adding row id to each record 
     SELECT ROW_NUMBER() OVER(ORDER BY [ID] ASC) AS Row, [ID], [Text] 
     FROM @A 
     /* 
      RowID ID Text 
      1  577 d 
      2  473 b 
      3  426 c 
      4  422 a 
     */ 
    ), TempSource ([CurrentID], [NextID], [CurrentText]) AS 
    (
     -- Getting the "Next" id of each record 
     SELECT DS1.[ID] 
       ,DS2.[ID] 
       ,DS1.[Text] 
     FROM DataSource DS1 
     LEFT JOIN DataSource DS2 
      ON DS1.[RowID] + 1 = DS2.[RowID] 
     /* 
      CurrentID NextID CurrentText 
      577   473  d 
      473   426  b 
      426   422  c 
      422   NULL a 
     */ 
    ) 
    SELECT TS.[CurrentID] AS [ID] 
      ,TS.[CurrentText] AS [Text] 
      ,B.[Text] AS [Appears] 
    FROM TempSource TS 
    LEFT JOIN @B AS B 
     ON TS.[CurrentID] < B.[ID] 
     AND TS.[NextID] > B.[ID] 
    ORDER BY TS.[CurrentID] 
    /* 
     ID Text Appears 
     422 a  yes 
     473 b  NULL 
     526 c  yes 
     577 d  NULL 
    */ 

SET NOCOUNT OFF 
GO 
+0

謝謝!工作很好。 –

+0

@AlexVacar歡迎您: - ] – gotqn

2

如果您有SQL Server 2012中,有一個很乾淨的方法:

DECLARE @A TABLE (id int, txt char(1)) 
INSERT @A VALUES (422,'a'),(473,'b'),(526,'c'),(577,'d') 

DECLARE @B TABLE (id int, appears char(1)) 
INSERT @B VALUES (465,'Y'), (569,'Y') 

SELECT 
    A.id, 
    A.txt, 
    B.appears 
FROM (
    SELECT 
    id, 
    txt, 
    LEAD(id) OVER(ORDER BY id) AS next_id 
    FROM @a 
) A 
LEFT OUTER JOIN @B B ON (B.id BETWEEN A.id AND A.next_id) 

如果沒有,你需要使用子查詢或自連接:

... 
    SELECT 
    id, 
    txt, 
    (SELECT MIN(id) FROM @a WHERE id > a1.id) AS next_id 
    FROM @a a1 
    ... 
+0

感謝您的回答!不幸的是我正在運行2008R2。 –

相關問題