mySQL在两个不同的表中计算类似的行

时间:2015-04-03 22:04:24

标签: mysql

我环顾四周,无法找到答案,我似乎无法解决这个问题。 我要找的是:

我有两张桌子: 表1:

+---------+---------------------+
| user_id | created_date        |
+---------+---------------------+
|       1 | 2013-05-17 11:59:59 |
|       1 | 2012-05-19 12:00:00 |
|       1 | 2014-06-11 12:00:02 |
|       1 | 2013-05-17 12:00:03 |
|       3 | 2014-01-12 14:05:00 |
|       3 | 2012-05-17 14:05:01 |
|       3 | 2013-05-17 15:30:00 |
+---------+---------------------+

表2:

+---------+---------------------+
| post_id | created_date        |
+---------+---------------------+
|       1 | 2013-05-17 11:59:59 |
|       1 | 2012-05-19 12:00:00 |
|       1 | 2014-06-11 12:00:02 |
|       1 | 2013-05-17 12:00:03 |
|       3 | 2014-01-12 14:05:00 |
|       3 | 2012-05-17 14:05:01 |
|       3 | 2013-05-17 15:30:00 |
+---------+---------------------+

我想要计算每个月数据库中的用户数和帖子数。 结果应该看起来像

+----------------+-------------+-------------+
| date           | users       | posts       |
+----------------+-------------+-------------+
| january 2013   | 27          | 10          |
| march 2013     | 108         | 101         |
| june 2013      | 270         | 100         |
| october 2013   | 2           | 1           |
+----------------+-------------+-------------+

我已经像这样启动了mySQL查询:

SELECT CONCAT_WS(' ', YEAR(u.date_created),MONTHNAME(u.date_created)) AS date,COUNT(*) AS users
FROM users AS u
UNION
SELECT CONCAT_WS(' ', YEAR(p.date_created),MONTHNAME(p.date_created)) AS date,COUNT(*) AS posts
FROM post AS p
GROUP BY YEAR(date_created),MONTHNAME(date_created)

但这只返回两列而不是三列。 任何帮助。

由于

4 个答案:

答案 0 :(得分:2)

我认为最简单的方法是计算所有用户(并将帖子数设置为NULL),然后计算所有帖子(并将用户数设置为NULL),然后使用UNION ALL组合两个查询的结果,最后使用SUM()和GROUP BY查询聚合计数:

SELECT
  `date`,
  SUM(users) AS users,
  SUM(posts) AS posts
FROM (
  SELECT
    DATE_FORMAT(date_created, '%M %Y') AS `date`,
    COUNT(*) AS users,
    NULL AS posts
  FROM
    users
  GROUP BY
    DATE_FORMAT(date_created, '%M %Y')

  UNION ALL

  SELECT
    DATE_FORMAT(date_created, '%M %Y') AS `date`,
    NULL AS users,
    COUNT(*) AS posts
  FROM
    posts
  GROUP BY
    DATE_FORMAT(date_created, '%M %Y')
) s
GROUP BY
  `date`

答案 1 :(得分:1)

使用YEAR_MONTH返回的公共EXTRACT值加入两个派生表:

SELECT 
    CONCAT_WS('-',
        YEAR(user_count.date_created), MONTHNAME(user_count.date_created)
    ) AS date,
    IFNULL(user_count,0) AS users,
    IFNULL(post_count,0) AS posts
FROM
    ( 
        SELECT 
        COUNT(user_id) AS user_count,
        EXTRACT(YEAR_MONTH FROM date_created) AS month_year,
        date_created
        FROM users
        GROUP BY month_year
  ) AS user_count
LEFT JOIN
    ( 
        SELECT COUNT(post_id) AS post_count,
        EXTRACT(YEAR_MONTH FROM date_created) AS month_year,
        date_created
        FROM posts
        GROUP BY month_year
    ) AS post_count 
ON post_count.month_year = user_count.month_year

答案 2 :(得分:0)

您需要加入这两个查询,而不是将它们合并。

SELECT u.date, users, posts
FROM (
    SELECT CONCAT_WS(' ', YEAR(date_created),MONTHNAME(date_created)) AS date, COUNT(*) AS users
    FROM users
    GROUP BY date) AS u
JOIN (SELECT CONCAT_WS(' ', YEAR(p.date_created),MONTHNAME(p.date_created)) AS date, COUNT(*) AS posts
    FROM post
    GROUP BY date) AS p
ON u.date = p.date

请注意,这只会返回同时包含用户和帖子的月份。如果MySQL有FULL OUTER JOIN你可以使用它来绕过它。如果这是一个问题,请使用fthiella的答案而不是这个答案。

答案 3 :(得分:0)

您正在使用一个union,它将两个结果堆叠在同一列中。您需要一个联接,其中日期为加入字段,用户和两个表中的帖子。从t1.date = t2.date上的table1 t1内部联接table2 t2中选择日期,用户和帖子。