将多个结果与条件组合

时间:2017-02-21 14:39:01

标签: mysql sql

假设我有多个查询:

SELECT col1, col2 FROM tab1 WHERE col1 = "%abc%";
SELECT colA, colB FROM tab2 WHERE colA = "%123%" AND colB IS NOT NULL;
SELECT colTest, colBlah FROM tab3;

每个查询只返回1个结果。

如何将这3个结果合并为1?

结果如下:

+------+------+------+------+---------+---------+
| col1 | col2 | colA | colB | colTest | colBlah |
+------+------+------+------+---------+---------+
| abc  | def  | Ghi  | JkL  | 12A     | 42BD    |
+------+------+------+------+---------+---------+

作为suggested here,我可以使用cross join。但是在哪里放置WHERE条件?
如果我把它们放在整个查询的末尾,我会得到一个空的结果,只有其中一个失败。这就是为什么我需要为每个查询单独放置它们。

3 个答案:

答案 0 :(得分:0)

假设每个查询只返回一行(如您的示例所示),您可以执行以下操作:

SELECT q1.col1, q1.col2, q2.colA, q2.colB, q3.colTest, q3.colBlah
FROM (SELECT col1, col2 FROM tab1 WHERE col1 = '%abc%') q1 CROSS JOIN
     (SELECT colA, colB FROM tab2 WHERE colA = '%123%' AND colB IS NOT NULL) q2 CROSS JOIN
     (SELECT colTest, colBlah FROM tab3) q3;

编辑:

您可以使用union all和聚合来处理缺失的数据(明确不是被问到的问题):

SELECT MAX(col1) as col1,
       MAX(col2) as col2,
       MAX(colA) as colA,
       MAX(colB) as colB,
       MAX(colTest) as colTest,
       MAX(colBlah) as colBlah
FROM ((SELECT col1, col2, NULL as colA, NULL a colB, NULL as colTest, NULL as colBlah
       FROM tab1
       WHERE col1 = '%abc%'
      ) UNION ALL
      (SELECT NULL, NULL, colA, colB, NULL, NULL
       FROM tab2
       WHERE colA = '%123%' AND colB IS NOT NULL
      ) UNION ALL
      (SELECT NULL, NULL, NULL, NULL, colTest, colBlah
       FROM tab3
      ) 
     ) t;

答案 1 :(得分:0)

不确定连接的id字段的名称是什么,但这些是可能的:

SELECT t1.col1, t1.col2,  t2.colA, t2.colB, t3. colTest, t3.colBlah
FROM tab1 t1
JOIN tab2 t2 On t1.tab1id = t2.tab1id
JOIN tab3 on t1.tab1id = t3.tab1id
WHERE t1.col1 = "%abc%";
            AND t2.colA = "%123%" 
            AND t2.colB IS NOT NULL;

SELECT t1.col1, t1.col2,  t2.colA, t2.colB, t3. colTest, t3.colBlah
FROM tab1 t1
LEFT JOIN tab2 t2 On t1.tab1id = t2.tab1id
LEFT JOIN tab3 on t1.tab1id = t3.tab1id
WHERE t1.col1 = "%abc%";
            AND t2.colA = "%123%" 
            AND t2.colB IS NOT NULL;    

如果您希望所有三个字段都包含每条记录的数据,请使用第一个查询。如果tab2或tab3中可能没有数据,那么第二个是合适的。如果只有一个可能没有数据,则只需要一个左连接。如果所有三个表中都没有数据,则使用完全连接。

答案 2 :(得分:0)

如果每个查询只返回一行,如您最初所述,那么您可以交叉加入行:

select * from (query#1) q1 cross join (query#2) q2  cross join (query#3) q3;

但是由于查询实际上可以返回零行或一行,所以您改为外连接:

select * 
from (query#1) q1 
full outer join (query#2) q2 on true 
full outer join (query#3) q3 on true;

(外部联接需要一个ON子句,我们实际上并不需要。所以我们在这里使用ON true,即无论记录内容如何都加入。)

但是,MySQL并不支持外连接。所以我们必须寻找另一种方法。返回无或一条记录的查询的一种简单方法是聚合:

SELECT ANY_VALUE(col1) AS col1, ANY_VALUE(col2) AS col2 FROM tab1 WHERE col1 = "%abc%";

这与

完全相同
SELECT col1, col2 FROM tab1 WHERE col1 = "%abc%";

仅在没有匹配的情况下,它返回一行空值而不是没有行。因此:

SELECT *
FROM 
  (SELECT ANY_VALUE(col1) AS col1, ANY_VALUE(col2) AS col2
   FROM tab1 WHERE col1 = "%abc%") q1
CROSS JOIN 
  (SELECT ANY_VALUE(colA) AS colA, ANY_VALUE(colB) AS colB
   FROM tab2 WHERE colA = "%123%" AND colB IS NOT NULL) q2
CROSS JOIN 
  (SELECT ANY_VALUE(colTest) AS colTest, ANY_VALUE(colBlah) AS colBlah 
   FROM tab3) q3;