MySQL同样查询多个表

时间:2013-07-26 03:58:03

标签: mysql

我需要查询具有相同列但内容不同的不同表。

表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

任何帮助都会非常感激。

2 个答案:

答案 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的副本,并针对该查询运行查询。

第一个查询略有不同,因为它会生成较小的集合以连接在一起。