如何在MySQL中做“横向UNION”? (连接表)

时间:2011-03-29 14:06:07

标签: mysql sql

我正在寻找连接或联合两个(或更多)表的可能性。我无法加入所有表,因为没有引用没有匹配的列。如果我在没有任何“开启”的情况下加入,我将从表1中获得所有数据乘以表2中的所有数据(不是我想要的)。所以我试图提供带有MySQL用户定义变量的假rownums,但由于所有表中都有不同数量的数据,我无法对其进行比较。这有点难以解释。所以我将提供一些例子。

示例1 (表1 = 4行,表2 = 3行,结果= 4行)

+---------+---------+---------------+
| Table 1 | Table 2 | Result        |
+---------+---------+-------+-------+
| Col 1   | Col 1   | Col 1 | Col 2 |
+---------+---------+-------+-------+
| A       | H       | A     | H     |
| B       | I       | B     | I     |
| C       | J       | C     | J     |
| D       |         | D     | NULL  |
+---------+---------+-------+-------+

示例2 (表1 = 3行,表2 = 4行,结果= 4行)

+---------+---------+---------------+
| Table 1 | Table 2 | Result        |
+---------+---------+-------+-------+
| Col 1   | Col 1   | Col 1 | Col 2 |
+---------+---------+-------+-------+
| A       | H       | A     | H     |
| B       | I       | B     | I     |
| C       | J       | C     | J     |
|         | K       | NULL  | K     |
+---------+---------+-------+-------+

示例3 (表1 = 3行,表2 = 4行,表3 = 2行,结果= 4行)

+---------+---------+---------+-----------------------+
| Table 1 | Table 2 | Table 3 | Result                |
+---------+---------+---------+-------+-------+-------+
| Col 1   | Col 1   | Col 1   | Col 1 | Col 2 | Col 3 |
+---------+---------+---------+-------+-------+-------+
| A       | H       | O       | A     | H     | O     |
| B       | I       | P       | B     | I     | P     |
| C       | J       |         | C     | J     | NULL  |
|         | K       |         | NULL  | K     | NULL  |
+---------+---------+---------+-------+-------+-------+

现在真正的困难部分。我需要这个作为查询。我不想填写其他临时表。如果可能: - )

2 个答案:

答案 0 :(得分:5)

我认为你加入了每个表的密集顺序等级,只是按“Col 1”值排序?

这实际上是每个表的等级的完全外连接。

不幸的是,MySQL不支持ROW_NUMBER()分析函数,这会使这个相对简单:

SELECT *
FROM (SELECT "Col 1", ROW_NUMBER() (OVER ORDER BY "Col 1") AS RowNum FROM "Table 1") AS T1
FULL OUTER JOIN (SELECT "Col 1", ROW_NUMBER() (OVER ORDER BY "Col 1") AS RowNum FROM "Table 2") AS T2
    ON T2.RowNum = T1.RowNum
FULL OUTER JOIN (SELECT "Col 1", ROW_NUMBER() (OVER ORDER BY "Col 1") AS RowNum FROM "Table 3") AS T3
    ON T3.RowNum = T2.RowNum
ORDER BY COALESCE(T1.RowNum, T2.RowNum, T3.RowNum)

MySQL中有其他选择,但我不熟悉解决方法。

就FULL OUTER JOIN解决方法而言,由于已知的排名只是自然数,所以排名很容易:

SELECT *
FROM Numbers
LEFT JOIN (SELECT "Col 1", ROW_NUMBER() (OVER ORDER BY "Col 1") AS RowNum FROM "Table 1") AS T1
    ON T1.RowNum = Numbers.Number
LEFT JOIN (SELECT "Col 1", ROW_NUMBER() (OVER ORDER BY "Col 1") AS RowNum FROM "Table 2") AS T2
    ON T2.RowNum = Numbers.Number
LEFT JOIN (SELECT "Col 1", ROW_NUMBER() (OVER ORDER BY "Col 1") AS RowNum FROM "Table 3") AS T3
    ON T2.RowNum = Numbers.Number
WHERE COALESCE(T1.RowNum, T2.RowNum, T3.RowNum) IS NOT NULL
ORDER BY Numbers.Number

答案 1 :(得分:0)

使用准备好的查询这是一个棘手的方法:

SET @r1= (SELECT COUNT(*) FROM table1);
SET @r2= (SELECT COUNT(*) FROM table2);
SET @a=-1;

SET @query= IF (@r1 > @r2, 
    (
        SELECT GROUP_CONCAT(CONCAT(
        'SELECT (SELECT col1 FROM table1 LIMIT ', @a:=@a+1, ', 1) AS col1,
        (SELECT col1 FROM table2 LIMIT ', @a, ', 1) AS col2 FROM table1')
        SEPARATOR ' union ') FROM table1
    ),
    (
        SELECT GROUP_CONCAT(CONCAT(
        'SELECT (select col1 from table1 limit ', @a:=@a+1,', 1) as col1,
        (SELECT col1 FROM table2 LIMIT ', @a, ', 1) AS col2 FROM table2')
        SEPARATOR ' union ') FROM table2
    )
);
PREPARE my_query FROM @query;
EXECUTE my_query;

记住它根本不是一种有效的方法,只是解决了你的问题。