4

以下に示すように、Names と Name_ids の 2 つのテーブルがあります。

プラットフォーム: SQL Server 2005/2008。

Names table:
    Nam                              ID
    -------------------------------- -----------
    A                                1
    B                                2
    C                                3
    D                                4
    E                                5
    F                                6
    G                                7
    H                                8

name_ids table

ID
-----------
3
6
8

これらのテーブルを結合して、次の出力を生成したいと思います。

Nam                              Nam_ID      ID
-------------------------------- ----------- -----------
A                                1           NULL
B                                2           NULL
C                                3           3
D                                4           3
E                                5           3
F                                6           6
G                                7           6
H                                8           8

ロジックは nam_id を id に一致させ、nam_id がどの id よりも小さい場合は NULL を返します。nam_id が id 以上の場合、id を返します。これがキャッチです。上記の例では、F,6 の場合、F,6,3 の組み合わせを返すべきではありませんが、一致する F,6,6 のみを返す必要があります。6,6 のように一致するアイテムが見つかった場合、6,3 のような他の一致をスキップする必要があります。その後、7,3 ではなく 7,6 を使用します。上記のSQLクエリを作成するにはどうすればよいですか? クエリは時間がかかり、高速に実行する必要があります。

Scripts:
Create table Names(Nam nvarchar(32), ID int);

insert into names values('A', 1);
insert into names values('B', 2);
insert into names values('C', 3);
insert into names values('D', 4);
insert into names values('E', 5);
insert into names values('F', 6);
insert into names values('G', 7);
insert into names values('H', 8);


Create table name_ids( ID int);
insert into name_ids values(3);
insert into name_ids values(6);
insert into name_ids values(8);

助けてください。

更新: ソリューションの提供にご尽力いただき、誠にありがとうございます。今、私は最高のパフォーマンスを発揮するクエリを選択するのに混乱しています. 私はいくつかを取り上げて、非常に大きな結果セットでパフォーマンスを分析しようとしました。

4

7 に答える 7

2

私の試みを確認してください:

SELECT 
    DISTINCT Nam, 
    a.ID Nam_ID, 
    MAX(b.ID) OVER (PARTITION BY Nam) ID
FROM 
    Names a LEFT JOIN name_ids b 
        ON a.ID>=b.ID
于 2013-07-05T11:50:41.753 に答える
1
select a.Nam, a.ID Nam_ID, 
      isnull(b.ID,(select max(id) from name_ids where id<a.id))
from Names a left outer join name_ids b
on (a.ID = b.ID);

ここでデモを見る

于 2013-07-05T11:43:00.207 に答える
1

試す:

with cte as
(select i.*, row_number() over (order by id) rn
 from name_ids i)
select na.Nam, na.id Nam_id, s.id
from Names na
left join (select c.id, n.id next_id
           from cte c
           left join cte n on c.rn+1 = n.rn) s
       on na.id >= s.id and na.id < coalesce(s.next_id, na.id+1)

ここでSQLFiddle 。

于 2013-07-05T11:51:24.740 に答える
0

それは簡単です:

SELECT A.Nam , A.Nam_ID , B.ID
FROM NAMES AS A 
OUTER APPLY
(
  SELECT MAX(ID) AS ID
  FROM NAME_IDS AS B WHERE A.ID >= B.ID  
) AS B

これは inline query のより単純なバージョンだと思います。

于 2013-07-05T11:49:35.950 に答える