如何编写从下表中生成以下输出的查询

时间:2015-07-20 04:59:41

标签: sql-server sql-server-2008

DECLARE @a TABLE (code INT, aname VARCHAR(10))
INSERT INTO @a(code, aname) SELECT 1,'A'
INSERT INTO @a(code, aname) SELECT 2,'B'
INSERT INTO @a(code, aname) SELECT 3,'C'

DECLARE @b TABLE (code INT, bname VARCHAR(10))
INSERT INTO @b(code, bname) SELECT 1,'aaa'
INSERT INTO @b(code, bname) SELECT 1,'bbb'
INSERT INTO @b(code, bname) SELECT 2,'ccc'
INSERT INTO @b(code, bname) SELECT 2,'ddd'

DECLARE @c TABLE (code INT, cname VARCHAR(10))
INSERT INTO @c(code, cname) SELECT 1,'xxx'
INSERT INTO @c(code, cname) SELECT 1,'yyy'
INSERT INTO @c(code, cname) SELECT 1,'zzz'
INSERT INTO @c(code, cname) SELECT 2,'www'

我需要以下输出

code        aname                            bname      cname
----------- ---------- ----------          ----------
1                  A                         aaa         xxx
1                  A                         bbb         yyy
1                  A                         NULL        zzz
2                  B                         ccc         www
2                  B                         ddd         NULL
3                  C                         NULL        NULL

我尝试此查询但它无法正常工作

SELECT * FROM @a as a 
LEFT JOIN @b  b On b.code = a.code 
LEFT JOIN @C c on  c.Code = A.Code

1 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER()PARTITION匹配记录,并使用两个单独的LEFT JOINS,然后执行FULL OUTER JOIN这样的操作。

<强> SQL Fiddle

示例数据

DECLARE @a TABLE (code INT, aname VARCHAR(10))
INSERT INTO @a(code, aname) SELECT 1,'A'
INSERT INTO @a(code, aname) SELECT 2,'B'
INSERT INTO @a(code, aname) SELECT 3,'C'

DECLARE @b TABLE (code INT, bname VARCHAR(10))
INSERT INTO @b(code, bname) SELECT 1,'aaa'
INSERT INTO @b(code, bname) SELECT 1,'bbb'
INSERT INTO @b(code, bname) SELECT 2,'ccc'
INSERT INTO @b(code, bname) SELECT 2,'ddd'

DECLARE @c TABLE (code INT, cname VARCHAR(10))
INSERT INTO @c(code, cname) SELECT 1,'xxx'
INSERT INTO @c(code, cname) SELECT 1,'yyy'
INSERT INTO @c(code, cname) SELECT 1,'zzz'
INSERT INTO @c(code, cname) SELECT 2,'www'

<强>查询

;WITH b1 AS 
(
SELECT *,ROW_NUMBER()OVER(PARTITION BY Code ORDER BY bname ASC) rn FROM @b
), c1 as 
(
SELECT *,ROW_NUMBER()OVER(PARTITION BY Code ORDER BY cname ASC) rn FROM @c
)
SELECT ISNULL(b.code,c.code) code, ISNULL(b.aname,c.aname) aname,bname,cname FROM 
(
    SELECT a.code,aname ,b.bname,rn
    FROM @a as a 
    LEFT JOIN b1 b ON b.code = a.code
) b
FULL OUTER JOIN
(
    SELECT a.code,aname ,c.cname,rn
    FROM @a as a 
    LEFT JOIN c1 c on  c.Code = A.Code
) c
ON b.code = c.code
    AND ISNULL(b.rn,0) = ISNULL(c.rn,0)
ORDER BY ISNULL(b.code,c.code),ISNULL(b.aname,c.aname)

<强>输出

code    aname   bname   cname
1   A   aaa xxx
1   A   bbb yyy
1   A   NULL    zzz
2   B   ccc www
2   B   ddd NULL
3   C   NULL    NULL