简体   繁体   中英

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.

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. I have tried a few methods such as UNION, SUBSELECT, but didn't have any success. The UNION didn't seem to work as intended and the SUBSELECT took 5 hours to run for only 128 rows.

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:

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. 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.

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.

我认为您可以在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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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