【问题标题】:MySQL Query: Group by same column name from two different tablesMySQL Query:按来自两个不同表的相同列名分组
【发布时间】:2021-06-25 06:45:24
【问题描述】:

我有两个表:questionanswer,它们都有 created_date 列,它定义了它们的创建日期。

question 表:

mysql> describe question;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| created_date | datetime     | NO   |     | NULL    |                |
| user_id      | int(11)      | NO   | MUL | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

answer 表:

mysql> describe answer;
+--------------+------------+------+-----+---------+----------------+
| Field        | Type       | Null | Key | Default | Extra          |
+--------------+------------+------+-----+---------+----------------+
| id           | int(11)    | NO   | PRI | NULL    | auto_increment |
| created_date | datetime   | NO   |     | NULL    |                |
| question_id  | int(11)    | NO   | MUL | NULL    |                |
| user_id      | int(11)    | NO   | MUL | NULL    |                |
+--------------+------------+------+-----+---------+----------------+

我想要的是获取有关用户的一些统计信息,即用户每天(或在某个日期范围内)发布的问题和答案的数量。

示例对于 id 为 1 的用户,请获取用户在过去 30 天内发布的问题和答案的数量(记录应按时间顺序排列)。

所需的输出如下所示:

+---------------------+-----------+---------+
| date                | questions | answers |
+---------------------+-----------+---------+
| 2021-01-02          |         0 |       1 |
| 2021-01-03          |         5 |       5 |
| 2021-01-04          |         1 |       0 |
| 2021-01-05          |         1 |       0 |
| 2021-01-06          |         5 |       2 |
+---------------------+-----------+---------+

我对 SQL 查询有所了解,但我相信这种类型的查询需要某种我从未理解过的 JOIN,并尽我所能避免它。

到目前为止我的想法(对于 id 为 1 的用户):

SELECT q.created_date, COUNT(q.id) 
FROM question q, answer a 
WHERE q.id = a.question_id 
AND q.user_id = 1 
GROUP BY CAST(q.created_date AS DATE) 
ORDER BY q.created_date ASC;

结果:

+---------------------+-------------+
| created_date        | count(q.id) |
+---------------------+-------------+
| 2021-01-02 13:47:15 |           4 |
| 2021-02-09 13:24:52 |           1 |
| 2021-03-02 18:31:14 |          12 |
+---------------------+-------------+

答案表应该有类似的输出。

如何将输出合并在一起?


编辑:

ID 为 2 的用户发布的所有日期和问题数量:

mysql> select cast(q.created_date as date) only_date, count(*) 
from question q 
where q.user_id = 2 
group by only_date;
+------------+----------+
| only_date  | count(*) |
+------------+----------+
| 2021-01-02 |        1 |
| 2021-02-10 |        1 |
| 2021-02-14 |        1 |
| 2021-03-16 |        1 |
| 2021-03-26 |        3 |
| 2021-03-27 |       23 |
| 2021-03-28 |        5 |
+------------+----------+

所有日期以及 id 为 2 的用户发布了多少答案:

mysql> select cast(a.created_date as date) only_date, count(*) 
from answer a 
where a.user_id = 2 
group by only_date;
+------------+----------+
| only_date  | count(*) |
+------------+----------+
| 2021-02-08 |        2 |
| 2021-02-14 |        1 |
+------------+----------+

期望的输出是:

+------------+-----------+---------+
| only_date  | questions | answers |
+------------+-----------+---------+
| 2021-01-02 |         1 |       0 |
| 2021-02-08 |         2 |       0 |
| 2021-02-10 |         1 |       0 |
| 2021-02-14 |         1 |       1 |
| 2021-03-16 |         1 |       0 |
| 2021-03-26 |         3 |       0 |
| 2021-03-27 |        23 |       0 |
| 2021-03-28 |         5 |       0 |
+------------+-----------+---------+

【问题讨论】:

  • 嗨,@Akina。我实际上是想在没有时间部分的情况下编写它,所以我会使用 CAST(created_date as DATE) 之类的东西来截断日期。我实际上不需要时间部分,只需要日期。我更新了问题。谢谢!

标签: mysql sql join group-by count


【解决方案1】:
SELECT CAST(q.created_date AS DATE) created_date, 
       COUNT(DISTINCT q.id) questions,    -- only unique values are counted
       COUNT(a.id) answers     -- if multiple answers for the same question
                               -- are possible, add DISTINCT too
FROM question q
JOIN answer a ON q.id = a.question_id 
WHERE q.user_id = 1 
GROUP BY created_date       -- output column, not source table column, is used
ORDER BY created_date ASC;

【讨论】:

    【解决方案2】:

    你没有告诉我们你在表之间创建的关系,这非常重要!所以我建议你在表之间建立参照完整性然后很容易从两个表中生成报告......这是你如何创建这种关系的演示

    CREATE TABLE t1 
    

    ( cid int 非空, 名称 Varchar(30), 指数(cid), 主键(cid) )TYPE=INNODB

    创建表 t2 ( tid int 非空, 金额整数,

    cid int NOT Null,
    PRIMARY KEY(tid),
    index(cid),
    FOREIGN KEY (cid) References t1(cid)
    

    )

    通过这样做,您可以将这些表链接到相同的 ID...

    【讨论】:

    • 嗨,对不起,我没有指定这个,但关系是:答案表有列 question_id,它是问题表中 id 列的外键。因此,如果我必须使用 WHERE 子句加入它们,则类似于:WHERE answer.question_id = question.id.
    【解决方案3】:
    SELECT q.created_date, COUNT(q.id) 
    FROM question q, answer a 
    INNER JOIN question ON a.question_id = q.id
    WHERE q.user_id = 1 
    GROUP BY CAST(q.created_date AS DATE) 
    ORDER BY q.created_date ASC;
    

    【讨论】:

      【解决方案4】:

      这样的查询应该会有所帮助。这不是一个有效的查询。只是个伪命题。请参见。 如果可能,将发布一个有效的查询。

      select
          t1.user_id, t1.date, t1.q_count, t2.ans_count
      from
          (
              select
              user_id, date, count(questions) q_count
              from
              question
              group by
              user_id, date
          ) t1
          left outer join
          (
              select
              user_id, date, count(questions) ans_count
              from
              question
              group by
              user_id, date
          ) t2 on t1.user_id = t2.user_id and t1.date = t2.date
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-15
        • 1970-01-01
        • 2012-04-27
        • 1970-01-01
        • 2012-02-18
        • 1970-01-01
        相关资源
        最近更新 更多