I have two tables Names and Name_ids as shown below.
Platform : SQL Server 2005/2008.
Names table:
Nam ID
-------------------------------- -----------
A 1
B 2
C 3
D 4
E 5
F 6
G 7
H 8
and
name_ids table
ID
-----------
3
6
8
I would like to produce following output joining these tables.
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
The logic is match the nam_id to id and if nam_id is less than any id then return NULL. If nam_id is greater than or equal to id, then return id. Here is the catch. In the above example, for F,6 we should not return F,6,3 combination but we should return only matching F,6,6. when a matching item is found like 6,6, it should skip other matches like 6,3. And after that use 7,6 and not 7,3. How do I write an sql query for the above? The query is time intensive and need to execute fast.
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);
Please help.
Update: I really appreciate your effort in providing solutions. Now I am confused to pick the best performing query. I have picked up few and trying to analyze the performance with very large result sets.
select n.Nam,
CASE WHEN ni.ID IS NULL THEN (SELECT MAX(ID) from name_ids n1 where
n1.ID < n.ID)
ELSE ni.ID
END
from Names n
left join name_ids ni on n.ID = ni.ID
SqlFiddle
Please check my attempt:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With