Я боролся с этим запросом уже несколько дней. Я использую PHP / MySQL.
Это система, в которой клиенты могут отправлять грузы для сбора или доставки компанией, для которой я разрабатываю. Запрос, который я пытаюсь написать, соберет сборы и поставки, выполненные для клиента, и отправит им сводку того, что они потратили в тот день.
У меня есть два набора результатов ниже, которые мне нужно "объединить", чтобы отправить отчет.
(Не беспокойтесь о специфике, проблема заключается в объединении :))
Набор результатов поставок
Этот результат представляет собой список (сгруппированный по дням) итогов доставки, которые компания доставила от имени перечисленных клиентов.
summary_day, num_cons, num_spaces, customer_code
2011-07-20 1 3 COB001P
2011-07-20 1 3 FAI001P
2011-07-20 2 2 FRE001P
2011-07-20 2 2 MIN001P
2011-07-20 17 29 NOR001P
2011-07-20 50 79 PAL001P
2011-07-20 1 1 PAR001P
2011-07-20 1 1 POT002P
2011-07-20 6 7 RHY001P
2011-07-20 9 13 TDG001P
2011-07-20 18 23 UPN001P
Набор результатов коллекций
Аналогично выше, но в обратном порядке этот результат представляет собой список итогов, собранных компанией от имени каждого клиента.
2011-07-20 9 15 ARR001P
2011-07-20 1 1 BAC002P
2011-07-20 1 1 BLA001P
2011-07-20 4 6 CAR003P
2011-07-20 2 2 DIS001P
2011-07-20 2 2 DOV001P
2011-07-20 1 1 DRY001P
2011-07-20 1 1 ECC001P
2011-07-20 3 5 FAI001P
2011-07-20 2 2 INV001P
2011-07-20 2 2 MIN001P
2011-07-20 3 3 PAL001P
2011-07-20 1 1 QUA002P
2011-07-20 1 1 TEC002P
2011-07-20 1 1 THE006P
2011-07-20 7 7 WIL005P
Проблема
Я борюсь с объединением, чтобы использовать для объединения этих двух наборов результатов.
В идеале конечный набор результатов должен быть довольно стандартным со столбцами:
summary_day, customer_code, num_deliveries, num_collections
Числовые поля будут столбцом num_spaces из каждого набора результатов. Если у клиента есть записи о сборе и доставке, покажите оба числа. Если у них есть один, а не другой, я использовал COALESCE, чтобы ожидать, что один столбец будет НЕДЕЙСТВИТЕЛЕН, и соответственно присвоить ему значение 0.
Я пытался использовать ПРАВИЛЬНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ В поле customer_code в надежде, что это даст ожидаемые результаты, но единственные результаты, которые я получаю:
2011-07-20, ARR001P, 0, 15
2011-07-20, BAC002P, 0, 1
2011-07-20, BLA001P, 0, 1
2011-07-20, CAR003P, 0, 6
2011-07-20, DIS001P, 0, 2
2011-07-20, DOV001P, 0, 2
2011-07-20, DRY001P, 0, 1
2011-07-20, FAI001P, 3, 5
2011-07-20, INV001P, 0, 2
2011-07-20, MIN001P, 2, 2
2011-07-20, PAL001P, 79, 3
2011-07-20, QUA002P, 0, 1
2011-07-20, TEC002P, 0, 1
2011-07-20, THE006P, 0, 1
2011-07-20, WIL005P, 0, 7
Как видите, результирующий набор только возвращает клиентов, у которых есть коллекции, что нормально, но мне также нужно видеть клиентов, у которых есть поставки и нет коллекций.
Например, примером может служить клиент NOR001P, который находится в наборе результатов поставок, но не в наборе результатов коллекций ...
Требуется ли ПОЛНОЕ НАРУЖНОЕ СОЕДИНЕНИЕ в этом сценарии? Если так, как я мог бы обойти это, учитывая, что MySQL не поддерживает FULL OUTER JOINs?
Спасибо, что нашли время, чтобы прочитать.
ПОЛНОЕ РЕШЕНИЕ
Благодаря ответу CResults, полное решение было следующим: как вы можете видеть, наборы результатов доставки и сбора были фактически составлены из подзапросов, так что это было немного головной болью!
set @summary_day = '2011-07-20';
select summary_day, customer_code, sum(num_deliveries) as pallet_deliveries, sum(num_collections) as pallet_collections
from
(
select d.summary_day, d.customer_code, d.num_spaces as num_deliveries, 0 as num_collections from
(select
@summary_day as summary_day, /* change variable */
count(*) as num_cons,
sum( coalesce(micro_qty,0) + coalesce(quarter_qty,0) + coalesce(half_qty,0) + coalesce(full_qty,0) + coalesce(ceil(vlu_qty),0) ) as num_spaces,
pc.customer_code
from pallet_routes pr
inner join pallet_consignments pc on pc.route_id = pr.route_id
where pr.date = @summary_day /* today */
and pc.type = 'D'
group by customer_code
) as d
union all
select c.summary_day, c.customer_code, 0 as num_deliveries, num_spaces as num_collections from
(select
@summary_day as summary_day, /* change variable */
count(*) as num_cons,
sum(coalesce(micro_qty,0) + coalesce(quarter_qty,0) + coalesce(half_qty,0) + coalesce(full_qty,0) + coalesce(ceil(vlu_qty),0)) as num_spaces,
pc.customer_code
from pallet_routes pr
inner join pallet_consignments pc on pc.route_id = pr.route_id
where pr.date = DATE_SUB(@summary_day, INTERVAL 1 DAY) /* Yesterday */
and pc.type = 'C'
group by customer_code
) as c
) as pallet_summaries
group by summary_day, customer_code