2014-12-23 3 views
0

ПочемуПодведение итогов нескольких столбцов - неожиданные результаты

Это дает неправильные результаты?

SELECT 
    people.name, 
    SUM(allorders.TOTAL), 
    SUM(allorders.DISCOUNT), 
    SUM(allorders.SERVICECHARGE), 
    SUM(payments.AMOUNT) 
FROM 
    people 
INNER JOIN 
    allorders ON allorders.CUSTOMER = people.ID 
INNER JOIN 
    payments ON payments.CUSTOMER = people.ID 
WHERE 
    people.ID = 7 AND allorders.VOIDED = 0 AND payments.VOIDED = 0 

дает: (имя), 1644000, 1100000, 50000, 1485000

Если я делаю это две таблицы в то время (INNER JOIN людей ON allorders.CUSTOMER = people.ID) в отдельных запросов , Я получаю правильные результаты. Я даже не знаю, откуда берутся цифры. Как:

SELECT 
    people.name, 
    SUM(allorders.TOTAL), 
    SUM(allorders.DISCOUNT), 
    SUM(allorders.SERVICECHARGE) 
FROM 
    people 
INNER JOIN 
    allorders ON allorders.CUSTOMER = people.ID 
WHERE people.ID = 7 AND allorders.VOIDED = 0 

дает: (имя), 822000, 550000, 25000

SELECT 
    people.name, 
    SUM(payments.AMOUNT) 
FROM 
    people 
INNER JOIN payments ON payments.CUSTOMER = people.ID 
WHERE people.ID = 7 AND payments.VOIDED = 0 

дает: (имя), 297000

Похоже, что в два раза, но я не» Знаю почему.

Странно, что у меня есть аналогичный запрос, который правильно выполняет эту сумму. Я отправлю его, но это немного сложно. Здесь:

SELECT 
    t1.IDENTIFIER, 
    ifnull(t1.NAME,""), 
    t1.PRICE, 
    t1.GUESTS, 
    t1.STATUS, 
    ifnull(t1.NOTE,""), 
    t1.LINK, 
    ifnull(t1.EDITOR,""), 
    concat(t2.FIRSTNAME,"",t2.LASTNAME), 
    t2.ID, 
    t3.ID, 
    ifnull(t1.EMAIL,""), 
    ifnull(t3.PHONE,""), 
    ifnull(SUM(p1.AMOUNT),0), 
    ifnull(SUM(o1.DISCOUNT),0), 
    ifnull(SUM(o1.TOTAL),0), 
    ifnull(SUM(o1.SERVICECHARGE),0) 
FROM 
    tables t1 
INNER JOIN 
    people t2 ON t1.SELLER = t2.ID 
INNER JOIN 
    people t3 ON t1.CUSTOMER = t3.ID 
INNER JOIN 
    orderpaymentinfo ON orderpaymentinfo.TABLEID = t1.IDENTIFIER 
INNER JOIN 
    payments p1 ON orderpaymentinfo.PAYMENTID = p1.PAYMENTID 
INNER JOIN 
    allorders o1 ON o1.ORDERID = orderpaymentinfo.ORDERID 
WHERE 
    p1.VOIDED = 0 AND o1.VOIDED = 0 AND t1.DATE = "2014-12-20" 
GROUP BY t1.IDENTIFIER 

Последний оператор выполняет одно и то же соединение, только он использует дополнительный вспомогательный стол. Мне жаль, что он немного плохо отформатирован (я не очень хорош в формате форматирования SO), но если кто-то может сказать мне разницу между логикой в ​​этих двух утверждениях и как можно совершенно ошибочно, а в другом праве, я бы будьте очень счастливы.

В ответ на ответ:

Результат 1:

Name - 5 

Результат 2:

Name - 2 

Результат 3:

Name - 10 

Результат 4 усекается в PhpMyAdmin - где я получу это без труда?

Структура таблицы для трех таблиц выглядит следующим образом:

ШОУ создают на пути.

+0

Хорошо, так что довольно ясно, что у вас есть некоторые неожиданные вещи для многих ко многим, которые происходят здесь, и вам нужно выяснить, что неясно. Я отвечу более длинный ответ в один момент в ответ, хотя сам ответ будет зависеть от некоторых запросов, которые вам нужно попробовать ... один момент – evanv

+0

Спасибо, кто отформатировал мой вопрос. Это потому, что я использую две таблицы (t2 и t3) в последнем запросе, что он работает? – nickdnk

+2

nickdnk проблема likey связана с отношением между людьми ко многим людям и платежам людей, вам может потребоваться определить, какой платеж предназначен для какого заказа на соединение, чтобы уменьшить искусственное раздувание суммы. Или, возможно, вам придется суммировать каждый отдельно, а затем добавлять результаты. То, что происходит, происходит в картезианском, чего вы не ожидаете. Устраните совокупность и посмотрите на конкретного пользователя, вы обнаружите проблему, если вы действительно понимаете данные и соединения. – xQbert

ответ

1

Итак, я уверен, что у вас есть условие соединения, которое в основном взрывает ваш результат в нечто вроде декартова.Вот что я думаю, вы должны попробовать

Во-первых, запустите следующую команду и разделить вывод:

SELECT p.name,COUNT(*) 
FROM people as p 
INNER JOIN allorders AS a 
ON a.CUSTOMER = p.ID 
WHERE p.ID = 7 AND a.VOIDED = 0 
GROUP BY p.name 

Затем запустите

SELECT p.name,COUNT(*) 
FROM people AS p 
INNER JOIN payments AS pay 
ON pay.CUSTOMER = p.ID 
WHERE p.ID = 7 AND pay.VOIDED = 0 
GROUP BY p.name 

Затем запустите

SELECT 
     p.name, 
     COUNT(*) 
    FROM 
     people as p 
    INNER JOIN 
     allorders as a ON a.CUSTOMER = p.ID 
    INNER JOIN 
     payments as pay ON pay.CUSTOMER = p.ID 
    WHERE 
     p.ID = 7 AND a.VOIDED = 0 AND pay.VOIDED = 0 
    GROUP BY p.name 

Последний запуск следующих

SHOW CREATE TABLE people; 
SHOW CREATE TABLE payments; 
SHOW CREATE TABLE allorders; 

Проблема в том, что у вас нет правильного понимания ваших данных. Вы должны дать нам немного больше информации о данных и отношениях, и результат, который я описал здесь, должен помочь. Мой не ответ. Но если вы запустите эти запросы и вставьте их вывод, вы сможете получить ответ либо от меня, либо от кого-то другого.

На основе обсуждения и редактирует выше, пожалуйста, попробуйте:

SELECT 
    p.name, 
    SUM(o.TOTAL), 
    SUM(o.DISCOUNT), 
    SUM(o.SERVICECHARGE), 
    MAX(pay.amt) 
FROM 
    people as p 
INNER JOIN 
    allorders AS o ON o.CUSTOMER = p.ID 
INNER JOIN (SELECT customer, 
      SUM(amount) as amt 
      FROM payments 
      WHERE voided = 0 AND customer = 7 
      GROUP BY customer) AS pay 
    ON pay.customer = p.id 
WHERE 
    p.ID = 7 AND o.VOIDED = 0 
GROUP BY p.name 

Вы также мог бы сделать подзапрос в вашем ЗЕЬЕСТЕ, но это довольно неприятно имо. Вы также можете сделать min (pay.amt) или avg или даже просто оставить агрегат в целом. Вышеизложенное должно работать ... хотя есть более чистые способы. Я предоставляю этот ответ, чтобы вы могли рассуждать о том, почему вы получили неожиданный результат ... на самом деле оптимизация вашего запроса - это другой вопрос, который вы можете погрузиться позже, как только у вас есть возможность просмотреть это

+0

Ну, человек сделал 5 заказов, но только 2 платежа. Как это плохо? 5 заказов находятся в таблице заказов, ссылаясь на таблицу людей, 2 платежа находятся в таблице платежей, снова ссылаясь на таблицу людей. Хотя я ценю тот факт, что вы говорите мне, что я не должен делать, у меня есть трудный вывод из этого, что я должен сделать вместо:/ – nickdnk

+0

@nickdnk Предполагая, что платежи производятся для оплаты заказов, Таблица платежей должна содержать столбец 'orderID'. Используйте этот столбец, чтобы присоединиться к 'payments' к' allorders' вместо того, чтобы присоединяться к 'people'. –

+0

Посмотрите на декартовы соединения. Это может помочь: http://stackoverflow.com/questions/12464037/two-sql-left-joins-produce-incorrect-result/12464135#12464135 – evanv

Смежные вопросы