2013-07-18 32 views
10

我有表SQL两个不相关的表合并成一个

table1的

col1 col2  
a  b 
c  d 

和表2

mycol1 mycol2 
e   f 
g   h 
i   j 
k   l 

我想这两个表,其中有没有共同的领域进入一个结合表看起来像:

表3

col1 col2 mycol1 mycol2 
a   b e f 
c   d g h 
null null i j 
null null k l 

即,它就像是把两个并排放在一起。

我被卡住了!请帮忙!

+1

其中RDBMS?你显然不想跨加入,但你希望如何排列行。即为什么e,f与a,b一起? – Randy

+3

通常,当问题是这样的时候,你正在做一些实际上没有意义的事情。你有什么用于并排表?如果您只是在应用程序中显示数据,那么可能比您提出的建议好得多。 – catfood

+0

sqlserver。嗨,e,f不需要跟a,b。表3中的列对彼此独立。 – user4109

回答

12

获取每个表中各行的行号,然后做用这些行号全联接:

WITH CTE1 AS 
(
    SELECT ROW_NUMBER() OVER(ORDER BY col1) AS ROWNUM, * FROM Table1 
), 
CTE2 AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY mycol1) AS ROWNUM, * FROM Table2 
) 
SELECT col1, col2, mycol1, mycol2 
FROM CTE1 FULL JOIN CTE2 ON CTE1.ROWNUM = CTE2.ROWNUM 

这是假设的SQL Server> = 2005

+0

好 - 除了这是特定于RDBM的 - 其他人可能会使用ROWNUM – Randy

+0

@Randy:谢谢;我添加了RDBMS警告。 – zimdanen

+0

这个效果很好,不管哪个表更长,谢谢。问题已解决 – user4109

1

这真是好,如果你把这个问题为什么需要解决的描述。我猜这只是练习sql语法?

无论如何,由于行没有任何连接它们,我们必须创建一个连接。我选择了它们的值的排序。此外,由于他们没有任何连接,所以也会提出一个问题,即为什么你想先把它们放在一起。

下面是完整的解决方案:http://sqlfiddle.com/#!6/67e4c/1

的选择代码如下所示:

WITH rankedt1 AS 
(
    SELECT col1 
    ,col2 
    ,row_number() OVER (order by col1,col2) AS rn1 
    FROM table1 
) 
,rankedt2 AS 
(
    SELECT mycol1 
    ,mycol2 
    ,row_number() OVER (order by mycol1,mycol2) AS rn2 
    FROM table2 
) 

SELECT 
col1,col2,mycol1,mycol2 
FROM rankedt1 
FULL OUTER JOIN rankedt2 
    ON rn1=rn2 
+1

非常感谢这一点,并@zimdanen答案,和sqlfiddle解决方案。 Blimey,你很快!我已经遇到了这个需求几次..它不是练习sql语法!该表的最终目的地是由第三方配置Sharepoint Web部件使用的。 – user4109

+0

这很好,不管哪个表更长,谢谢。已解决问题 – user4109

+0

我在需要从通过继承与另一个表对应的表中提取标识索引值时使用了它。没有其他特定的数据将这两者链接起来,因为层次结构中的最高表由许多与各自中的特定数据无关的表继承。 – blindguy

2

选项1:单查询

加入两个表,如果你希望table1中的每一行只与table2中的一行相匹配,那么你的就有来限制连接。我怎么样。计算每个表中的行数并加入该列。行号是数据库特定的;这里是一个mysql的解决方案:

SELECT 
    t1.col1, t1.col2, t2.mycol1, t2.mycol2 
FROM 
    (SELECT col1, col2, @t1_row := t1_row + 1 AS rownum FROM table1, (SELECT @t1_row := 0) AS r1) AS t1 
    LEFT JOIN 
    (SELECT mycol1, mycol2, @t2_row := t2_row + 1 AS rownum FROM table2, (SELECT @t2_row := 0) AS r2) AS t2 
    ON t1.rownum = t2.rownum; 

这假设table1比table2更长;如果table2较长,则使用RIGHT JOIN或切换t1和t2子选择的顺序。另请注意,您可以使用子选择中的ORDER BY子句分别指定每个表的顺序。

(见select increment counter in mysql

选项2:后处理

考虑做两个选择,然后连接用你最喜欢的脚本语言的结果。这是一个更合理的方法。

+1

我回头看你的答案!实际上,我不知道table1是否比表2长。最初的问题是这个问题的一个非常简单的例子。实际上,将会有十几个表被合并成一个视图(即不是表,但这不重要)。预先不知道每个十几个表的大小。第三方得到的观点,所以选项2是不可行的。 – user4109

+0

@ user4109顺便说一句,如果你不知道哪个更长,你可以在'UNION'中通过左连接和右连接在mysql中执行'完全外连接'。 – jmilloy