首页 > 解决方案 > 从 3 个不同的表中选择 3 个不同的列 (COUNT) 并按日期分组

问题描述

我有 3 个不同的表格,用于跟踪售出的钢笔、铅笔和墨水的数量。

**pens table:**
date         who_bought
12.03.2020   a
12.03.2020   d
13.03.2020   b
14.03.2020   c

**pencils table:**
date         who_bought
12.03.2020   z
16.03.2020   r
17.03.2020   j
17.03.2020   k

**ink table:**
date         who_bought
11.03.2020   h
11.03.2020   j
13.03.2020   z
17.03.2020   r

我想汇总数据并获取每天售出的钢笔、墨水和铅笔的数量。“who_bought”列不相关(我的意思是值)。我只想计算每天的记录数。最后,我想按日期排序。在上述情况下,我想得到类似的结果

11.03.2020 pens:0 pencils:0 ink: 2
12.03.2020 pens:2 pencils:1 ink: 0
13.03.2020 pens:1 pencils:0 ink:1
14.03.2020 pens:0 pencils:0 ink:0
16.03.2020 pens:0 pencils:1 ink:0
17.03.2020 pens:0 pencils:2 ink:1

如何做到这一点?我尝试过这样的事情,但它不起作用:

select
    COUNT(pens.*) as pens,
    COUNT(pencils.*) as pencils,
    COUNT(ink.*) as ink,
    DATE(date) as date
from
    pens
    full join pencils on pencils.date=pens.date
    full join ink on ink.date=pens.date
group by
    date
order by
    date asc

标签: mysqlsqljoingroup-bypivot

解决方案


您的使用尝试full join是在正确的轨道上;不幸的是,MySQL 不支持这种语法。

您可以使用union all条件聚合来做到这一点:

select
    date,
    sum(what = 'pens')    no_pens,
    sum(what = 'pencils') no_pencils,
    sum(what = 'ink')     no_inks
from (
    select 'pens' what, date from pens
    union all select 'pencils', date from pencils
    union all select 'ink', date from ink
) t
group by date

如果您想要所有日期,包括没有任何产品销售的日期,那么情况会有所不同。基本上,你需要一个日历表。这是使用递归查询的一种方法(仅在 MySQL 8.0 中可用)。

with dates as (
    select min(date) date, max(date) max_date
    from (
        select date from pens
        union all select date from pencils
        union all select date from ink
    ) t
    union all 
    select date + interval 1 day from cte where date < max_date
)
select 
    d.date, 
    pn.no_pens, 
    pl.no_pencils,
    ik.no_inks 
from dates d
left join (select date, count(*) no_pens    from pens    group by date) pn on pn.date = d.date
left join (select date, count(*) no_pencils from pencils group by date) pl on pl.date = d.date
left join (select date, count(*) no_inks    from inks    group by date) ik on ik.date = d.date

推荐阅读