1

根据以下逻辑填充 FINAL TABLE 中第三列的最简洁方法是什么:

如果介于 2 个连续记录之间,则分配B.appears给“上”记录。TABLE AB.idA.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
4

2 回答 2

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
  ...
于 2013-07-10T23:10:18.113 回答
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
于 2013-07-11T06:41:22.447 回答