SQL Server:匹配具有相同名称的列

时间:2018-01-04 07:15:46

标签: sql sql-server

将列与名称匹配,如果第一个表有两个相同的名称(测试),第二个表有三个相同的名称(测试)意味着第一个表第3个应该为空,第二个表第3行应该是'测试'

create table #tmp1
( 
     name varchar(100),
     price decimal(10, 2)
)

insert into #tmp1 values('Test', 200.00)
insert into #tmp1 values('Test', 100.00)
insert into #tmp1 values('Test1', 500.00)
insert into #tmp1 values('Test1', 300.00)

create table #tmp
(
     name varchar(100),
     price decimal(10,2)
)

insert into #tmp values('Test', 200.00)
insert into #tmp values('Test', 300.00)
insert into #tmp values('Test', 400.00)
insert into #tmp values('Test1', 300.00)
insert into #tmp values('Test3', 300.00)

预期输出

Name  price  Name Price
Test  200.00 Test  200.00
Test  100.00 Test  300.00
             Test  400.00
Test1 300.00 Test1 300.00
Test1 500.00 

3 个答案:

答案 0 :(得分:0)

看来你正在寻求一个完整的外部联接。

SELECT TMP1.NAME NAME1, TMP1.PRICE PRICE1, TMP.NAME, TMP.PRICE INTO COMMON_TMP
FROM TMP1 INNER JOIN TMP 
ON TMP1.NAME = TMP.NAME AND TMP1.PRICE = TMP.PRICE;

SELECT * FROM COMMON_TMP
UNION ALL
SELECT A.NAME AS NAME1, A.PRICE AS PRICE1, B.NAME, B.PRICE
FROM
    (SELECT TMP1.NAME, TMP1.PRICE, ROW_NUMBER() OVER (PARTITION BY TMP1.NAME ORDER BY (SELECT 1)) AS RNUM FROM TMP1 LEFT JOIN COMMON_TMP C ON TMP1.NAME = C.NAME AND TMP1.PRICE = C.PRICE WHERE C.NAME IS NULL OR C.PRICE IS NULL) A
    FULL OUTER JOIN
    (SELECT TMP.NAME, TMP.PRICE, ROW_NUMBER() OVER (PARTITION BY TMP.NAME ORDER BY (SELECT 1)) AS RNUM FROM TMP LEFT JOIN COMMON_TMP C ON TMP.NAME = C.NAME AND TMP.PRICE = C.PRICE WHERE C.NAME IS NULL OR C.PRICE IS NULL) B
    ON A.NAME = B.NAME AND A.RNUM = B.RNUM
    WHERE (B.NAME IN (SELECT DISTINCT TMP1.NAME FROM TMP1 INNER JOIN TMP ON TMP1.NAME = TMP.NAME) OR B.NAME IS NULL)
    AND (A.NAME IN (SELECT DISTINCT TMP1.NAME FROM TMP1 INNER JOIN TMP ON TMP1.NAME = TMP.NAME) OR A.NAME IS NULL)
ORDER BY NAME1, PRICE;

答案 1 :(得分:0)

使用row_numberfull join

select t1.name, t1.price,
       t2.name, t2.price
from
(
  select *, row_number() over (partition by name order by price) rn
  from #tmp1 t1
  where exists(select 1 from #tmp t2 where t1.name = t2.name)
) t1
full join (
  select *, row_number() over (partition by name order by price) rn
  from #tmp t1
  where exists(select 1 from #tmp1 t2 where t1.name = t2.name)  
) t2 on t1.name = t2.name and t1.rn = t2.rn

存在用于消除第二个表中没有适当镜像的结果

dbfiddle demo

答案 2 :(得分:0)

试试这个:

    create table #tmp1
    ( 
            name varchar(100),
            price decimal(10, 2)
    )

    insert into #tmp1 values('Test', 200.00)
    insert into #tmp1 values('Test', 100.00)
    insert into #tmp1 values('Test1', 500.00)
    insert into #tmp1 values('Test1', 300.00)

    create table #tmp
    (
            name varchar(100),
            price decimal(10,2)
    )

    insert into #tmp values('Test', 200.00)
    insert into #tmp values('Test', 300.00)
    insert into #tmp values('Test', 400.00)
    insert into #tmp values('Test1', 300.00)
    insert into #tmp values('Test3', 300.00)

    ;with cte1
    As(
        select Row_Number() OVer(Partition by name order by name ,price) rn1 ,* from #tmp1
    )


    ,

    cte2
    As(
        select Row_Number() OVer(Partition by name order by name,price ) rn2 ,* from #tmp
    )


        SELECT c1.Name,c1.price,c2.Name,c2.price
        FROM cte1 c1 
        FULL OUTER JOIN cte2 c2 ON c1.rn1 = c2.rn2 and c1.Name=c2.Name 
        WHERE (c2.Name in (Select name from cte1) or c1.Name in (Select name from cte2))
        order by ISNULL(c1.Name,c2.Name)




    Drop table #tmp1
    Drop table #tmp