说我有两张桌子:
table_A table_B
+----+ +----+
| id | | id |
+----+ +----+
| 1 | | 3 |
| 2 | | 4 |
+----+ +----+
我想要的是表的UNION
,但是将table_B中的记录作为单独的列,而不是其他行。行之间不需要任何关联,例如JOIN
。
示例结果集如下所示:
+------+------+
| a.id | b.id |
+------+------+
| 1 | 3 |
| 2 | 4 |
+------+------+
我可以接近
SELECT a.id, b.id FROM
(SELECT id, 'nothing' from table_A) a JOIN
(SELECT id, 'nothing' from table_B) b ON a.nothing = b.nothing
但是这会产生两倍的行数:
+------+------+
| a.id | b.id |
+------+------+
| 1 | 3 |
| 2 | 3 |
| 1 | 4 |
| 2 | 4 |
+------+------+
和GROUP BY
或a.id
上的b.id
会丢失未归类的列中的一个值。
每张桌子的大小可能会有所不同。如果一个表大于另一个表,则NULL
值应放在较短的列中。
答案 0 :(得分:3)
非平凡&
现在已经过测试:SQL FIDDLE 现在更新以处理包含来自两个表的所有记录的要求。 SQL Fiddle
我会使用用户变量为每个表中的每一行指定一个特定的行号,然后加入用户变量。加入伪列值“无”的原因是,如您所见,它对另一个表中的每个值使用一次EACH ID,因此当您需要1:1时会产生1:M。通过分配行号,我们保证每行只使用一次;因此是1:1的关系。
假设两个表都有不相等的行,那么具有更多记录的表将被截止,从而消除较高的行数是可以接受的。
如果您愿意,可以使用外部(左,右)连接,以便显示包含更多ID的表的所有记录,但您必须知道哪个表具有更多的第一个。
SELECT C.ID, D.ID
FROM (SELECT id, @row:=@row+1 RN
FROM table_A
CROSS JOIN (select @row:=0) a
ORDER BY ID) C
INNER JOIN (SELECT id, @row2:=@row2+1 RN
FROM table_B
CROSS JOIN (select @row2:=0) b
ORDER BY ID) D
on C.RN = D.RN
我还应用了一个订单,以便每个表的低ID对齐。
现在,如果您不知道哪个表会有更多记录......
您可以使用以下内容模拟MYSQL中的完整外部联接...
SELECT C.ID, D.ID
FROM (SELECT id, @row:=@row+1 RN
FROM table_A
CROSS JOIN (select @row:=0) a
ORDER BY ID) C
LEFT JOIN (SELECT id, @row2:=@row2+1 RN
FROM table_B
CROSS JOIN (select @row2:=0) b
ORDER BY ID) D
on C.RN = D.RN
UNION
SELECT C.ID, D.ID
FROM (SELECT id, @row:=@row+1 RN
FROM table_A
CROSS JOIN (select @row:=0) a
ORDER BY ID) C
RIGHT JOIN (SELECT id, @row2:=@row2+1 RN
FROM table_B
CROSS JOIN (select @row2:=0) b
ORDER BY ID) D
on C.RN = D.RN
请注意union
vs union all
Union做了一个与众不同的内容,它将删除使用union all
答案 1 :(得分:2)
您也可以使用以下查询执行此操作:
SELECT ra.id, rb.id
FROM (
select @anr:=(@anr+1) as nr, a.* from table_a a JOIN (SELECT @anr:=0 ) as init ) ra
LEFT JOIN (
select @bnr:=(@bnr+1) as nr, b.* from table_b b JOIN (SELECT @bnr:=0 ) as init ) rb
ON ra.nr = rb.nr;
<强>样品强>
MariaDB [l]> select * from table_a;
+----+
| id |
+----+
| 1 |
| 2 |
+----+
2 rows in set (0.00 sec)
MariaDB [l]> select * from table_b;
+----+
| id |
+----+
| 2 |
| 4 |
+----+
2 rows in set (0.00 sec)
MariaDB [l]> SELECT ra.id, rb.id
-> FROM (
-> select @anr:=(@anr+1) as nr, a.* from table_a a JOIN (SELECT @anr:=0 ) as init ) ra
-> LEFT JOIN (
-> select @bnr:=(@bnr+1) as nr, b.* from table_b b JOIN (SELECT @bnr:=0 ) as init ) rb
-> ON ra.nr = rb.nr;
+----+------+
| id | id |
+----+------+
| 1 | 2 |
| 2 | 4 |
+----+------+
2 rows in set (0.00 sec)
MariaDB [l]>
答案 2 :(得分:2)
您需要MySQL没有的两个功能:
为了解决这些缺失的功能,您可以使用如下查询:
select a.id,b.id
from
(
SELECT @rownum:=@rownum + 1 as row_number, t1.id
FROM (
select id from table_A order by id
) t1,
(SELECT @rownum := 0) r1
) a
left outer join
(
SELECT @rownum2:=@rownum2 + 1 as row_number, t2.id
FROM (
select id from table_B order by id
) t2,
(SELECT @rownum2 := 0) r2
) b on b.row_number = a.row_number
union
select c.id,d.id
from
(
SELECT @rownum3:=@rownum3 + 1 as row_number, t3.id
FROM (
select id from table_A order by id
) t3,
(SELECT @rownum3 := 0) r3
) c
right outer join
(
SELECT @rownum4:=@rownum4 + 1 as row_number, t4.id
FROM (
select id from table_B order by id
) t4,
(SELECT @rownum4 := 0) r4
) d on d.row_number = c.row_number
答案 3 :(得分:0)
我结合了几个答案:
SELECT A.id, B.id FROM
(
SELECT @ca:=(@ca+1) as c FROM table_a JOIN (SELECT @ca:=0) as init
UNION
SELECT @cb:=(@cb+1) as c FROM table_b JOIN (SELECT @cb:=0) as init
) as maxrows
LEFT JOIN
(
SELECT @c2:=(@c2+1) as c2, id FROM table_a JOIN (SELECT @c2:=0) as init
) as A on (c = c2)
LEFT JOIN
(
SELECT @c3:=(@c3+1) as c3, id FROM table_b JOIN (SELECT @c3:=0) as init
) as B on (c = c3)
第一个联合获取最大行数(如果两个表具有不同的行数),然后我们可以简单地将它连接到编号表。