MySQL лучший способ объединить несколько запросов - PullRequest
1 голос
/ 04 ноября 2011

MySQL новичок здесь.У меня есть эти три отдельных запроса.Каждый из них группируется по годам и выбирает одно дополнительное поле.

-- tickets_by_hosts
select 
    yearweek(r.created_at) as week,
    count(zt.id) as tickets_by_hosts
from reservations r
inner join zendesk_tickets zt on zt.reservation_code = r.confirmation_code and zt.requester_id = r.host_id
where 
    r.created_at > '2011-8-20 00:00:00' and status != 0
group by yearweek(r.created_at)
order by week desc


-- tickets_by_guests
select 
    yearweek(r.created_at) as week,
    count(zt.id) as tickets_by_guests
from reservations r
inner join zendesk_tickets zt on zt.reservation_code = r.confirmation_code and zt.requester_id = r.guest_id
where 
    r.created_at > '2011-8-20 00:00:00' and status != 0
group by yearweek(r.created_at)
order by week desc

-- reservations
select 
    yearweek(r.created_at) as week,
    count(r.id) as reservations
from reservations r
where 
    r.created_at > '2011-8-20 00:00:00' and status != 0
group by yearweek(r.created_at)
order by week desc

Как лучше всего объединить эти три запроса, чтобы результаты выстраивались по годам:Спасибо!Гуглил, но пока не повезло.

1 Ответ

3 голосов
/ 04 ноября 2011

В вашем случае это не должны быть отдельные запросы. Вы можете реализовать условную логику в статистической функции (SUM, COUNT и т. Д.), Используя CASE.

select 
    yearweek(r.created_at) as week,
    SUM(CASE WHEN zt.requester_id = r.host_id THEN 1 ELSE 0 END ) as tickets_by_hosts,
    SUM(CASE WHEN zt.requester_id = r.guest_id THEN 1 ELSE 0 END ) as tickets_by_guests,
    COUNT(*) AS reservations,
from reservations r
inner join zendesk_tickets zt 
    on zt.reservation_code = r.confirmation_code 
where 
    r.created_at > '2011-8-20 00:00:00' and status != 0
group by yearweek(r.created_at)
order by week desc

менее эффективный подход был бы:

SELECT Q1.Week, Q1.Tickets_by_hosts, Q2.Tickets_by_guests, Q3.reservations
FROM (
        select 
            yearweek(r.created_at) as week,
            count(zt.id) as tickets_by_hosts
        from reservations r
        inner join zendesk_tickets zt on zt.reservation_code = r.confirmation_code and zt.requester_id = r.host_id
        where 
            r.created_at > '2011-8-20 00:00:00' and status != 0
        group by yearweek(r.created_at)
        order by week desc
     ) Q1
     INNER JOIN (
                    select 
                        yearweek(r.created_at) as week,
                        count(zt.id) as tickets_by_guests
                    from reservations r
                    inner join zendesk_tickets zt on zt.reservation_code = r.confirmation_code and zt.requester_id = r.guest_id
                    where 
                        r.created_at > '2011-8-20 00:00:00' and status != 0
                    group by yearweek(r.created_at)
                    order by week desc
                ) Q2 
            ON Q1.week = Q2.Week
    INNER JOIN (
                select 
                    yearweek(r.created_at) as week,
                    count(r.id) as reservations
                from reservations r
                where 
                    r.created_at > '2011-8-20 00:00:00' and status != 0
                group by yearweek(r.created_at)
                order by week desc  
               ) Q3
            ON Q1.week = Q3.week

Для второго примера я переписал запрос, чтобы использовать каждый из примеров, которые вы опубликовали в качестве подзапроса (или производной таблицы), а затем соединил их вместе. В этом случае, однако, БД будет выполнять всю работу по сканированию таблиц и вычислению агрегатов несколько раз, у вас также будет работа по сбору динамических наборов результатов и их объединению (из-за природы этих наборов результатов, у вас действительно не будет большой пользы от индексов. Этот второй вариант неправильный, но я включил его, чтобы вы знали, как использовать производную таблицу, которая может пригодиться в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...