如何将sql server中的两个表与一个公共列组合,但没有冗余数据

时间:2011-07-13 22:58:45

标签: sql-server-2008

表A:

id  members      
____________
1    a
2    b
3    c
4    c
4    d
5    e

表B

id  countries
_____________
1   us
1   europe
1   australia
3   india
3   china
4   australia
4   canada
5   mexico

结果应该是

id   members   countries
___________________________
1     a        us
1              europe
1              australia
2     b
3     c        india
3              china
4     c        australia
4     d        cananda
5     e         mexico

如果我在错误的地方编辑,我很抱歉。

@Martin感谢您的回复。它适用于2张桌子。但实际上我想要合并超过2个。假设我有另一个表C

id     prime_members
---------------------
1       p1
1       p2

我需要结果看起来像

id   members   countries     prime_mem
___________________________________________
1     a        us            p1
1              europe        p2
1              australia
2     b
3     c        india
3              china
4     c        australia
4     d        cananda
5     e         mexico

所以我尝试了这样的查询

 ;WITH A AS 
( SELECT id, members,
 ROW_NUMBER() OVER (PARTITION BY id ORDER BY members) AS RN FROM @A ),
  B AS 
  ( SELECT id, countries, 
  ROW_NUMBER() OVER (PARTITION BY id ORDER BY countries) AS RN FROM @B ),
   C AS 
  ( SELECT id,PRIME_MEM,
  ROW_NUMBER() OVER (PARTITION BY id ORDER BY PRIME_MEM) AS RN FROM @C )

   SELECT COALESCE(A.id,B.id,C.ID) AS id,  A.members, B.countries,C.PRIME_MEM
    FROM A FULL OUTER JOIN B on A.id = B.id AND A.RN=B.RN
    FULL OUTER JOIN C  ON A.ID =C.ID AND C.RN = A.RN 

然后我得到了这样的结果:

id   members   countries     prime_mem
___________________________________________
1     a        us            p1
1              europe        
1              australia
1                            p2
2     b
3     c        india
3              china
4     c        australia
4     d        cananda
5              mexico

我认为C.RN=B.RN给出了正确的输出,因为A.RN没有RN>1,因为它只有1行。这里很容易,因为只有3个表和几行。但实时如何弄清楚并解决这个问题。表A也是参考表,即表B和C中的ID值将出现在表A中。

感谢任何帮助。 感谢。

1 个答案:

答案 0 :(得分:2)

表没有“自然顺序”(除非有一个额外的列,例如你没有向我们展示的id),没有什么可以用来确保你的示例源数据中的顺序将保留在最终输出中。

;WITH A AS
(
SELECT id,
       members, 
       ROW_NUMBER() OVER (PARTITION BY id ORDER BY members) AS RN
FROM tableA
),
B AS
(
SELECT id,
       countries, 
       ROW_NUMBER() OVER (PARTITION BY id ORDER BY countries) AS RN
FROM tableB
)
SELECT COALESCE(A.id,B.id) AS id, 
       A.members,
       B.countries
FROM A FULL OUTER JOIN B on A.id = B.id AND A.RN=B.RN

返回(注意中国和印度在每个组中按字母顺序交换了地点作为答案顺序)

id          members countries
----------- ------- ---------
1           a       australia
1           NULL    europe
1           NULL    us
2           b       NULL
3           c       china
3           NULL    india
4           c       australia
4           d       canada
5           NULL    mexico