简体   繁体   English

MySQL:如何将多个查询合并为一个使用具有不同条件的同一表的查询?

[英]MySQL: How can I combine multiple queries into one that use same table with different conditionals?

I have several queries which are similar and only differ in the conditional clause. 我有几个类似的查询,只是条件子句不同。 I am trying to combine all the queries into a single one. 我正在尝试将所有查询合并为一个查询。

The first query looks like this: 第一个查询如下所示:

First query: 第一个查询:

SELECT pages.title, 
       YEAR(page_revisions.date) AS year,
       MONTH(page_revisions.date) AS MONTH, 
       COUNT(revid) AS Cadmin_edits 
FROM page_revisions 
    INNER JOIN pages ON page_revisions.title=pages.title
WHERE userid!=0 AND admin=1 AND pages.ns=0 
GROUP BY year, MONTH 
ORDER BY page_revisions.title, year, MONTH;

+--------------+------+-------+--------------+
| title        | year | MONTH | Cadmin_edits |
+--------------+------+-------+--------------+
| Bangalore    | 2002 |    11 |            4 |
| Bangalore    | 2003 |     2 |            2 |
| Bangalore    | 2003 |     5 |            1 |
| Bangalore    | 2003 |     6 |            6 |
| Bangalore    | 2003 |     8 |            4 |
| Bangalore    | 2003 |     9 |            3 |
| Bangalore    | 2003 |    10 |            2 |
| Bart Simpson | 2002 |     9 |            4 |
| Bart Simpson | 2007 |     3 |           33 |
| Bart Simpson | 2007 |     7 |           15 |
| Bart Simpson | 2008 |    11 |           19 |
| Batman       | 2001 |    12 |            5 |

The second query is very similar, only difference is in the conditional wikip_member=1 instead of admin. 第二个查询非常相似,唯一的区别是条件wikip_member = 1而不是admin。

Second query: 第二个查询:

SELECT pages.title, 
       YEAR(page_revisions.date) AS year, 
       MONTH(page_revisions.date) AS MONTH, 
       COUNT(revid) AS Wpart_edits 
FROM page_revisions 
    INNER JOIN pages ON page_revisions.title=pages.title
WHERE userid!=0 AND wikip_member=1 AND pages.ns=0 
GROUP BY year, MONTH
ORDER BY page_revisions.title, year, MONTH;

+------------------------------------------+------+-------+-------------+
| title                                    | year | MONTH | Wpart_edits |
+------------------------------------------+------+-------+-------------+
| 1906 Florida Keys hurricane              | 2011 |    10 |         266 |
| 1906 Florida Keys hurricane              | 2011 |    11 |         108 |
| 1906 Florida Keys hurricane              | 2012 |     2 |          66 |
| 1969 race riots of Singapore             | 2007 |     6 |         124 |
| 1969 race riots of Singapore             | 2008 |     2 |         143 |
| 1969 race riots of Singapore             | 2009 |     1 |         151 |
| 1980 Winter Olympics                     | 2003 |     8 |           3 |
| 1980 Winter Olympics                     | 2003 |    10 |           7 |
| 1980 Winter Olympics                     | 2004 |     3 |          16 |
| Babe Ruth                                | 2004 |     5 |          22 |
| Babe Ruth                                | 2004 |     7 |          21 |
| Bangalore                                | 2002 |    11 |           6 |
| Bangalore                                | 2003 |     2 |           2 |
| Bangalore                                | 2004 |     2 |           9 |

Essentially what I need the output to look like is like this: 本质上,我需要输出看起来像这样:

Intended output: 预期输出:

+------------------------------------------+------+-------+--------+-------+
| title                                    | year | MONTH | Cadmin | Wpart |
+------------------------------------------+------+-------+--------+-------+
| 1906 Florida Keys hurricane              | 2011 |    10 |     0  |   266 |
| 1906 Florida Keys hurricane              | 2011 |    11 |     0  |   108 |
| 1906 Florida Keys hurricane              | 2012 |     2 |     0  |    66 |
| 1969 race riots of Singapore             | 2007 |     6 |     0  |   124 |
| 1969 race riots of Singapore             | 2008 |     2 |     0  |   143 |
| 1969 race riots of Singapore             | 2009 |     1 |     0  |   151 |
| 1980 Winter Olympics                     | 2003 |     8 |     0  |     3 |
| 1980 Winter Olympics                     | 2003 |    10 |     0  |     7 |
| 1980 Winter Olympics                     | 2004 |     3 |     0  |    16 |
| Babe Ruth                                | 2004 |     4 |     0  |     7 |
| Babe Ruth                                | 2004 |     8 |     0  |    21 |
| Bangalore                                | 2002 |    11 |     4  |     6 |
| Bangalore                                | 2003 |     2 |     2  |     2 |
| Bangalore                                | 2003 |     5 |     1  |     0 |
| Bangalore                                | 2003 |     6 |     6  |     0 |
| Bangalore                                | 2003 |     8 |     4  |     0 |
| Bangalore                                | 2003 |     9 |     3  |     0 |
| Bangalore                                | 2003 |    10 |     2  |     0 |
| Bangalore                                | 2004 |     2 |     0  |     9 |

Which would be a combination of the queries. 这将是查询的组合。 Basically getting the COUNT of the revisions for each month and showing a 0 when no revisions that matches the conditions are found for that month. 基本上获取每个月的修订版本数,如果在该月份没有找到与条件匹配的修订版本,则显示0。 I have tried a few methods such as UNION, SUBSELECT, but didn't have any success. 我尝试了一些方法,例如UNION,SUBSELECT,但没有成功。 The UNION didn't seem to work as intended and the SUBSELECT took 5 hours to run for only 128 rows. UNION似乎没有按预期工作,SUBSELECT花了5个小时才只运行128行。

UNION ATTEMPT: 联盟尝试:

SELECT pages.title, 
       YEAR(page_revisions.date) AS year,
       MONTH(page_revisions.date) AS MONTH, 
       COUNT(revid) AS Cadmin, 
       null AS Wpart 
FROM page_revisions 
    INNER JOIN pages ON page_revisions.title=pages.title 
WHERE userid!=0 AND admin=1 AND pages.ns=0 
UNION 
SELECT pages.title, 
       mid( page_revisions.date, 1, 4) AS year, 
       mid(page_revisions.date, 6, 2) AS MONTH, 
       null as Cadmin,
       COUNT(revid) AS Wpart_edits 
FROM page_revisions 
    INNER JOIN pages ON page_revisions.title=pages.title 
WHERE userid!=0 AND wikip_member=1 AND pages.ns=0 
GROUP BY year, MONTH 
ORDER BY title, year, MONTH;

SUBSELECT ATTEMPT: SUBSELECT ATTEMPT:

SELECT pages.title, 
       YEAR(page_revisions.date) AS year,
       MONTH(page_revisions.date) AS MONTH, 
       (SELECT COUNT(revid) AS Cadmin_edits FROM page_revisions WHERE YEAR(page_revisions.date)=year and MONTH(page_revisions.date)= month and userid!=0 AND admin=1) 
FROM page_revisions 
    INNER JOIN pages ON page_revisions.title=pages.title
WHERE pages.ns=0 
GROUP BY year, MONTH 
ORDER BY pages.title, year, MONTH;

Any help pointing me in the right direction would be greatly appreciated. 向我指出正确方向的任何帮助将不胜感激。 This is for my final presentation which is due on Friday and this is the last query I need to wrap everything together. 这是我的最后一次演讲,应在星期五进行,这是我需要将所有内容包装在一起的最后一个查询。

In MySql (and many other SQL dialects), you can join to a subselect. 在MySql(以及许多其他SQL方言)中,您可以加入子选择。 This should perform better, as the engine will run the query once to produce a single result set, as opposed to running a subquery that is part of the select clause once per row of the initial results. 这样做会更好,因为引擎将运行查询一次以生成单个结果集,而不是对初始结果的每一行运行一次属于select子句一部分的子查询。

So, you'd try something like this: 因此,您可以尝试执行以下操作:

select COALESCE(a.title, b.title), 
   COALESCE(a.year, b.year), 
   COALESCE(a.month, b.month),
   COALESCE(a.Cadmin_edits, 0),
   COALESCE(b.Wpart_edits, 0)
FROM (SELECT pages.title, 
      YEAR(page_revisions.date) AS year,
      MONTH(page_revisions.date) AS MONTH, 
      COUNT(revid) AS Cadmin_edits 
   FROM page_revisions 
   INNER JOIN pages ON page_revisions.title=pages.title
   WHERE userid!=0 
      AND admin=1 
      AND pages.ns=0 
   GROUP BY year, MONTH 
   ORDER BY page_revisions.title, year, MONTH) a
FULL JOIN (SELECT pages.title, 
      YEAR(page_revisions.date) AS year, 
      MONTH(page_revisions.date) AS MONTH, 
      COUNT(revid) AS Wpart_edits 
   FROM page_revisions 
   INNER JOIN pages ON page_revisions.title=pages.title 
   WHERE userid!=0 
      AND wikip_member=1 
      AND pages.ns=0 
   GROUP BY year, MONTH 
   ORDER BY page_revisions.title, year, MONTH) b 
ON a.title = b.title AND a.year = b.year AND a.month = b.month
/*order the full results as you please*/

If this were Oracle or Sql Server, I would have recommended a couple of common table expressions for the subqueries, as they would allow you to remove the subquery from the main query, making the full query easier to understand. 如果这是Oracle或Sql Server,我将为子查询推荐几个常用的表表达式,因为它们将允许您从主查询中删除子查询,从而使完整查询更容易理解。

我认为您可以在WHERE userid!=0 AND(admin=1 OR wikip_member=1)如果我得到正确的WHERE userid!=0 AND(admin=1 OR wikip_member=1)

SELECT pages.title, 
YEAR(page_revisions.date) AS iYear,
MONTH(page_revisions.date) AS iMonth, 
COUNT(revid) AS Cadmin_edits,
0 AS Wpart_edits 
FROM page_revisions 
INNER JOIN pages 
ON page_revisions.title=pages.title
WHERE userid <> 0 
AND [admin] = 1 
AND pages.ns = 0 
GROUP BY pages.title, YEAR(page_revisions.date), MONTH(page_revisions.date) 

UNION ALL   

SELECT pages.title, 
YEAR(page_revisions.date), 
MONTH(page_revisions.date),
    0,
    COUNT(revid)
FROM page_revisions 
INNER JOIN pages 
    ON page_revisions.title=pages.title
WHERE userid <> 0 
AND wikip_member = 1 
AND pages.ns = 0 
GROUP BY pages.title, YEAR(page_revisions.date), MONTH(page_revisions.date)

ORDER BY title, iYear, iMonth;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM