问题 sql将两个不相关的表合并为一个


我有桌子

表格1

col1    col2    
a       b
c       d

和table2

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

也就是说,就像把两张桌子并排放在一起。

我被卡住了!请帮忙!


4735
2017-07-18 14:11


起源

哪个RDBMS?你显然不希望跨越连接,但是你希望如何排列行。即为什么e,f与a,b? - Randy
通常当问题是这样的时候,你做的事情实际上并没有意义。您对并排表有什么用处?如果您只是这样做以在您的应用程序中显示数据,那么可能比您建议的方式更好。 - catfood
SQLSERVER。嗨,e,f不需要a,b。表3中的列对彼此独立。 - user4109
结果表将由使用sharepoint的人使用。给他们一张桌子玩起来要容易得多 - 这就是我被要求提供的东西,即使它没有意义! - user4109
有些人只是让我做一个像这样工作的报告,虽然很容易说'sql不能像那样工作',但很难解释为什么这么难。我打赌这会增加很多。 - codeulike


答案:


获取每个表中每行的行号,然后使用这些行号进行完全连接:

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。


13
2017-07-18 14:22



好 - 除了这是RDBM特定的 - 其他人可能使用ROWNUM - Randy
@Randy:谢谢;我添加了RDBMS警告。 - zimdanen
无论哪个表更长,这都很有效,谢谢。问题解决了 - user4109
@ user4109:很高兴得到帮助,欢迎来到StackOverflow。如果有机会,请标出答案,帮助您解决问题。 - zimdanen
这是一个警告:如果您执行的操作超过两列,则最终可能会出现多余的行(即所有列中可能至少有一个NULL)。我发现的解决方法是从表中包含最多元素的最终外部SELECT并加入较短的列表,这不是一个理想的解决方案,因为您并不总是知道哪个列表最长。 - Techrocket9


选项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子选择的顺序。另请注意,您可以使用a分别指定每个表的顺序 ORDER BY 子选择中的子句。

(看到 在mysql中选择增量计数器

选项2:后处理

考虑进行两次选择,然后将结果与您喜欢的脚本语言连接起来。这是一种更合理的方法。


2
2017-07-18 15:28



我回来看你的答案了!实际上,我不知道table1是否比表2更长。最初的问题是问题的一个非常简单的例子实际上,将有十几个表组合成一个视图(即不是表,但这并不重要)。事先不知道十几个表中每个表的大小。第三方获取视图,因此选项2不可行。 - user4109
@ user4109顺便说一句,如果你不知道哪个会更长,你可以在mysql中做一个'全外连接' UNION 左连接和右连接。 - jmilloy


如果你描述为什么需要解决这个问题,这真的很好。我猜它只是练习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
2017-07-18 14:29



非常感谢,@ zimdanen回答,以及sqlfiddle解决方案。 Blimey,你很快!我几次遇到这个要求..它不是练习sql语法!该表的最终目的地供配置共享点Web部件的第三方使用。 - user4109
无论哪个表更长,这都很有效,谢谢。问题解决了 - user4109
当我需要通过继承从对应于另一个表的表中提取身份索引值时,我使用它。没有其他特定数据链接两者,因为层次结构中的最高表由许多表继承,这些表与每个表中的特定数据无关。 - blindguy