Мне нужно определить лучший способ сделать несколько агрегатов для разных таблиц, которые объединены в запрос SQL.Объединение результатов из разных таблиц в одном запросе SQL
Учитывая следующие таблицы для управления гостиницей, планирования обслуживания, советами клиентов и оценками клиентов:
Room
id | name
----+------
1 | 101
2 | 102
3 | 103
4 | 201
5 | 202
6 | 203
housekeeper
id | name | age
----+----------+-----
1 | John | 48
2 | Veronica | 25
3 | Bob | 19
room_service_planning
id | date | room_id | housekeeper_id
----+------------+---------+----------------
1 | 2014-11-01 | 3 | 2
2 | 2014-11-01 | 1 | 2
3 | 2014-11-02 | 5 | 1
tips
id | amount | housekeeper_id
----+--------+----------------
1 | 5,00 € | 1
2 | 2,00 € | 3
3 | 2,00 € | 1
4 | 3,00 € | 3
client_eval
id | good_eval | housekeeper_id
----+-----------+----------------
1 | t | 1
2 | f | 1
3 | t | 2
4 | t | 2
менеджер хочет знать для каждого запланированного обслуживания, который присваивается ему, подсказки сумма, количество оценок клиентов и количество положительных оценок клиентов, которые этот сотрудник получил в своей карьере.
Ожидаемый результат при поиске обслуживания между 2014-11-01 и 2014-11-02 это что-то вроде:
id | date | room_id | housekeeper_id | hk_name | hk_tips_sum | hk_tot_eval | hk_pos_eval
----+------------+---------+----------------+----------+-------------+-------------+-------------
1 | 2014-11-01 | 3 | 2 Veronica 2 2
2 | 2014-11-01 | 1 | 2 Veronica 2 2
3 | 2014-11-02 | 5 | 1 John 7,00 € 2 1
Растворов я исследовал, чтобы получить этот результат:
решения 1:
SELECT temp2.id as id, temp2.date as date, temp2.room_id as room_id,
temp2.housekeeper_id as housekeeper_id, temp2.hk_name as hk_name,
temp2.hk_tips_sum as hk_tips_sum, temp2.hk_tot_eval as hk_tot_eval,
count(1) as hk_post_eval
FROM
(
SELECT temp.id as id, temp.date as date, temp.room_id as room_id,
temp.housekeeper_id as housekeeper_id, temp.hk_name as hk_name,
temp.hk_tips_sum as hk_tips_sum, count(1) as hk_tot_eval
FROM
(SELECT rsp.id as id, rsp.date as date, rsp.room_id as room_id,
rsp.housekeeper_id as housekeeper_id, hk.name as hk_name,
sum(t.amount) as hk_tips_sum
FROM room_service_planning rsp
INNER JOIN housekeeper hk
ON rsp.date>='2014-11-01'
AND rsp.date<='2014-11-02'
AND hk.id=rsp.housekeeper_id
LEFT JOIN tips t
ON t.housekeeper_id=hk.id
GROUP BY rsp.id, rsp.date, rsp.room_id, rsp.housekeeper_id, hk_name
) temp
LEFT JOIN client_eval ce_tot
ON ce_tot.housekeeper_id=temp.housekeeper_id
GROUP BY temp.id, temp.date, temp.room_id, temp.housekeeper_id,
temp.hk_name, temp.hk_tips_sum
) temp2
LEFT JOIN client_eval ce_pos
ON ce_pos.housekeeper_id=temp2.housekeeper_id
AND ce_pos.good_eval='t'
GROUP BY temp2.id, temp2.date, temp2.room_id, temp2.housekeeper_id,
temp2.hk_name, temp2.hk_tips_sum, temp2.hk_tot_eval;
Примечание: это основано на «группе агрегировать» т «присоединитесь к следующей таблице», затем «группируйте по агрегированию», затем «присоединитесь к следующей таблице» и т. д. .... Это работает, но очень тяжело писать и читать трудно. Я не удовлетворен этим решением.
Решение 2:
SELECT rsp.id as id, rsp.date as date, rsp.room_id as room_id,
rsp.housekeeper_id as houkeeper_id, hk.name as hk_name,
t.amount as hk_tips_sum, ce_tot.hk_tot_eval as hk_tot_eval,
ce_pos.hk_pos_eval as hk_pos_eval
FROM room_service_planning rsp
INNER JOIN housekeeper hk
ON rsp.date>='2014-11-01'
AND rsp.date<='2014-11-02'
AND hk.id=rsp.housekeeper_id
LEFT JOIN
(SELECT housekeeper_id, sum(amount) as amount
FROM tips
GROUP BY housekeeper_id) t
ON t.housekeeper_id=hk.id
LEFT JOIN
(SELECT housekeeper_id, count(1) as hk_tot_eval
FROM client_eval
GROUP BY housekeeper_id) ce_tot
ON ce_tot.housekeeper_id=hk.id
LEFT JOIN
(SELECT housekeeper_id, count(good_eval) as hk_pos_eval
FROM client_eval
WHERE good_eval='t'
GROUP BY housekeeper_id) ce_pos
ON ce_pos.housekeeper_id=hk.id;
Примечание: это решение более читаемым, но мне интересно, что происходит, число записей растет на «советы» или «client_eval». Предположим, что в отеле миллионы подсказок и миллионы клиентов eval. Это означает, что мы будем делать миллионы сумм и счетов, а затем мы просто выберем те из них, которые вам нужны. Это пустая трата ресурсов и может привести к очень долгим задержкам.
Заключение: Несмотря на то, что я нашел два разных способа достижения своей цели, я не удовлетворен ими.
Какое умное и эффективное решение вы могли бы предложить решить эту проблему?
Ваши оценки не подключен к услуге. Похоже, что в конце концов вы получаете неправильный оценочный номер. –
Пила тоже, но проблема заключается в том, что агрегаты предназначены для карьеры экономки, а не для предстоящих (и как таковых, не связанных или связанных с оценками) запланированного назначения услуг. –
Вы правы, эта система не полностью согласована. Я просто построил его, чтобы объяснить мою проблему. Моя оригинальная система слишком сложна, чтобы объясняться здесь. – Nitseg