SQL join 1 line and return NULLs for others

时间:2015-07-28 16:19:17

标签: sql sql-server-2008

Is it possible to stop SQL from duplicating lines from a table when creating a JOIN to a table with more than one line?

Table 1

Car Name    Colour  Size
Car 1       Red     big
car 2       Blue    small
Car 3       Green   small

Table 2

Car Name    Part Number
Car 1       123456
Car 1       234567
Car 1       345678
Car 2       ABCDEFG
Car 2       BCDEFGH
Car 2       CDEFGHI

Then Join Table 1 with Table 2 on "Car Name" but only have the information once from each table,

Resulting SQL View

Car Name    Colour  Size    Part Number
Car 1       Red     big     123456
NULL        NULL    NULL    234567
NULL        NULL    NULL    345678
Car 2       Blue    small   ABCDEFG
NULL        NULL    NULL    BCDEFGH
NULL        NULL    NULL    CDEFGHI

edit: if the original "Car Name" column is duplicated this isn't a problem, that's not really made clear above because i've put NULL's under that column but i understand that's the column its joined on and that information is already on the lines of the second table, its more being able to stop the duplication of the other information that isn't in table 2

3 个答案:

答案 0 :(得分:0)

As mentioned in comments it is recommend to do this kind of data formatting on client application but still if need a sql answer then try something like this.

WITH cte 
     AS (SELECT RN=Row_number() over(PARTITION BY a.Car_Name ORDER BY (SELECT NULL)), 
                a.car_name, 
                a.color, 
                a.size, 
                b.part_number 
         FROM   table1 
                INNER JOIN table2 
                        ON a.car_name = b.car_name) 
SELECT car_name=CASE WHEN rn = 1 THEN car_name ELSE NULL END, 
       color=CASE WHEN rn = 1 THEN color ELSE NULL END, 
       size=CASE WHEN rn = 1 THEN size ELSE NULL END, 
       part_number 
FROM   cte 

答案 1 :(得分:0)

You would just need to assign a ROW_NUMBER() and populate table1 fields only when row number = 1 something like this:

WITH q1
AS (
    SELECT t2.*
        ,row_number() OVER (
            PARTITION BY t2.CarName ORDER BY PartNumber
            ) AS rn
    FROM table2 t2
    )
SELECT CASE 
        WHEN q1.rn = 1
            THEN t1.CarName
        ELSE NULL
        END AS CarName
    ,CASE 
        WHEN q1.rn = 1
            THEN t1.Colour
        ELSE NULL
        END AS Colour
    ,CASE 
        WHEN q1.rn = 1
            THEN t1.Size
        ELSE NULL
        END AS Size
    ,q1.PartNumber
FROM q1
INNER JOIN table1 t1 ON t1.carname = q1.carname

SQL Fiddle Demo

答案 2 :(得分:0)

试,

declare @t table(CarName varchar(10),Colour varchar(10),  Size varchar(10))
insert into @t (carname,Colour,Size) values
('Car 1',       'Red',     'big'),
('car 2','Blue','small'),
('car 3','Gr een','small')

declare @t1 table(CarName varchar(10),part varchar(10))
insert into @t1 (carname,part) values
('car 1','123456'),
('car 1','2345670'),
('car 1','345678'),
('car 2','ABCDEFG'),
('car 2','BcDEFGH'),
('car 2','cDEFGHI')

select t.*, t1.part from @t t right  join
(select carname,part, row_number() over (partition by carname order by part) rno from @t1) 
t1 on t.CarName=(case when t1.rno=1 then t1.CarName else null end)