我需要查询具有相同列但内容不同的不同表。
表A:
ID DocDate Type
1 2013-05-01 A
2 2013-05-01 B
3 2013-05-02 D
4 2013-05-04 D
表B:
ID DocDate Type
1 2013-05-01 F
2 2013-05-03 G
3 2013-05-03 G
4 2013-05-05 H
我需要什么:
COUNT(Tablea.ID) COUNT(Tableb.ID) DocDate
2 1 2013-05-01
1 NULL 2013-05-02
NULL 2 2013-05-03
1 NULL 2013-05-04
NULL 1 2013-05-05
任何帮助都会非常感激。
答案 0 :(得分:0)
尝试
SELECT d.docdate, a.total totala, b.total totalb
FROM
(
SELECT docdate
FROM tablea
UNION
SELECT docdate
FROM tableb
) d LEFT JOIN
(
SELECT docdate, COUNT(*) total
FROM tablea
GROUP BY docdate
) a ON d.docdate = a.docdate LEFT JOIN
(
SELECT docdate, COUNT(*) total
FROM tableb
GROUP BY docdate
) b ON d.docdate = b.docdate
ORDER BY d.docdate
输出:
| DOCDATE | TOTALA | TOTALB | -------------------------------- | 2013-05-01 | 2 | 1 | | 2013-05-02 | 1 | (null) | | 2013-05-03 | (null) | 2 | | 2013-05-04 | 1 | (null) | | 2013-05-05 | (null) | 1 |
这是 SQLFiddle 演示
答案 1 :(得分:0)
有两种方法可以获得这个结果。
返回指定行的最有效查询可能是:
SELECT NULLIF(SUM(c.cnt_a_id),0) AS cnt_a_id
, NULLIF(SUM(c.cnt_b_id),0) AS cnt_b_id
, c.DocDate
FROM (
SELECT COUNT(a.ID) AS cnt_a_id
, 0 AS cnt_b_id
, a.DocDate AS DocDate
FROM Table_A a
GROUP BY a.DocDate
UNION ALL
SELECT 0
, COUNT(b.ID)
, b.DocDate
FROM Table_B b
GROUP BY b.DocDate
) c
GROUP BY c.DocDate
每个表的(DocDate, ID)
上的合适覆盖索引将有利于大型集合的性能。
另一个更容易理解但更昂贵的方法是创建表的UNION,然后执行GROUP BY。
SELECT NULLIF(COUNT(c.a_id)) AS cnt_a_id
, NULLIF(COUNT(c.b_id)) AS cnt_b_id
, c.DocDate
FROM (
SELECT a.ID AS a_id
, NULL + 0 AS b_id
, a.DocDate AS DocDate
FROM Table_A a
UNION ALL
SELECT NULL + 0 AS a_id
, b.ID AS b_id
, b.DocDate AS DocDate
FROM Table_B b
) c
GROUP BY c.DocDate
(第二个查询的效率较低,因为MySQL将内联视图中的查询实现为临时MyISAM表;第二个查询基本上创建了一起连接在一起的Table_A和Table_B的副本,并针对该查询运行查询。
第一个查询略有不同,因为它会生成较小的集合以连接在一起。