2016-04-12 4 views
1

У меня есть три таблицы:MySQL Query - SUM из COUNT из нескольких таблиц

  • клиентов: идентификатор, имя
  • contracts_jewels: идентификатор, customer_id, оплаченные, переданы final_date
  • контракты_объекты: id, customer_id, paid, transfer, final_date

Как вы видите, структура последних двух таблиц одинакова. «заплатил» и «переданы» поля содержат значение 0 или 1.

Что мне нужно сделать запрос, который должен вернуть все клиенты (независимо от того, если у них есть контракты или нет) и для каждого клиента: идентификатор, имя, count_contracts_all, count_contracts_active

где:

  • count_contracts_all будет означать сумму [SELECT COUNT (*) FROM contracts_jewels ГДЕ customer_id = 3 (к примеру)] и [SELECT COUNT (*) FROM contracts_objects WHERE customer_id = 3 (к примеру)]
  • count_contracts_active будет означать сумму [SELECT COUNT (*) FROM contracts_jewels ГДЕ customer_id = 3 и final_date> = Теперь() и оплаченных = 0 и переносили = 0] и [SELECT COUNT (*) оТ contracts_objects ГДЕ customer_id = 3 AND final_date> = Now() AND paid = 0 AND передано = 0]

Любая идея? Не могли бы вы помочь мне? Спасибо!

+0

Я думаю, что UNION может помочь вам: 'ВЫБРАТЬ field_1 [, field_2 ...] ОТ table_1 [, table_2 ...] UNION [ALL] ВЫБРАТЬ field_a [, field_b ...] ОТ TABLE_A [ , table_b, ...]; ' – Holger

ответ

0

Вы можете рассчитывать на контракты по отдельности, а затем просто присоединиться к их клиентам:

SELECT 
    c.id, 
    COALESCE(oc.active_count,0) + COALESCE(jc.active_count,0) as count_contracts_active, 
    COALESCE(oc.total_count,0) + COALESCE(jc.total_count,0) as count_contracts_all 
FROM customers c 
LEFT JOIN (
    SELECT 
     customer_id 
     COUNT(*) as total_count, 
     COUNT(IF(final_date>=Now() AND paid=0 AND transferred=0,1,NULL)) as active_count 
    FROM contracts_jewels 
    GROUP BY customer_id 
) as oc ON oc.customer_id = c.id 
LEFT JOIN (
    SELECT 
     customer_id 
     COUNT(*) as total_count, 
     COUNT(IF(final_date>=Now() AND paid=0 AND transferred=0,1,NULL)) as active_count 
    FROM contracts_objects 
    GROUP BY customer_id 
) as jc ON jc.customer_id = c.id 
+0

Это похоже на очарование! Спасибо! Я боюсь, что не могу оценить ваш ответ, я здесь новый пользователь, но я очень благодарен! – fortitude23

+0

@ fortitude23: вы еще не можете оценить, но вы все равно можете «принять» ответ, если он поможет вам решить вашу проблему – Preuk

0

Одно быстрое решение, я могу думать прямо сейчас:

SELECT COUNT(`temp_table`.*) FROM (
    SELECT * FROM contracts_jewels WHERE customer_id=3 UNION ALL 
    SELECT * FROM contracts_objects WHERE customer_id=3) AS `temp_table` 

И

SELECT COUNT(`temp_table`.*) FROM (
SELECT * FROM contracts_jewels WHERE customer_id=3 AND final_date>=Now() AND paid=0 AND transferred=0 UNION ALL 
    SELECT * FROM contracts_objects WHERE customer_id=3 AND final_date>=Now() AND paid=0 AND transferred=0) AS `temp_table` 
0

Вы можете присоединиться к каждой из этих таблиц дважды и добавить их соответствующие COUNT s в ваш результат:

SELECT 
    c.id, 
    (COUNT(cj1.id)+COUNT(co1.id)) AS count_contracts_all, 
    (COUNT(cj2.id)+COUNT(co2.id)) AS count_contracts_active 
FROM 
    customers c 
    LEFT OUTER JOIN contracts_jewels cj1 ON c.id = cj1.customer_id 
    LEFT OUTER JOIN contracts_objects co1 ON c.id = co1.customer_id 
    LEFT OUTER JOIN contracts_jewels cj2 ON 
     c.id = cj2.id AND 
     cj2.final_date >= NOW() AND 
     cj2.paid = 0 AND 
     cj2.transferred = 0 
    LEFT OUTER JOIN contracts_object co2 ON 
     c.id = co2.id AND 
     co2.final_date >= NOW() AND 
     co2.paid = 0 AND 
     co2.transferred = 0 
GROUP BY c.id 

Примечание: Я не запускаю это, но, надеюсь, он устанавливает вас в правильном направлении.