Выберите 3 разных столбца (COUNT) из 3 разных таблиц и сгруппируйте по дате - PullRequest
1 голос
/ 21 марта 2020

У меня есть 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

1 Ответ

2 голосов
/ 21 марта 2020

Ваша попытка использования 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
...