2014-10-21 4 views
1

У меня есть задание, которому нужен этот запрос: Напишите оператор SELECT, который возвращает одну строку для каждого клиента, имеющего существующий порядок. Включите эти столбцы: таблицу EmailAddress из таблицы Customers, сумму покупок из таблицы orderitems (количество * цена) и сумму скидок из таблицы orderitems (discountAmount * количество). Сортируйте результирующий набор в нисходящей последовательности по общей цене товара для каждого клиента.Группа по запросу, возвращающему более одной строки

Обычный столбец между таблицей Customers или таблицы OrderItems отсутствует, поэтому я сделал соединение с тремя таблицами. Используя заказы table.I закончили с этим кодом:

SELECT EmailAddress, SUM(ItemPrice)*Quantity AS TotalSum, SUM(DiscountAmount)*Quantity AS  TotalDiscount 
FROM Customers JOIN Orders 
ON Customers.CustomerID = Orders.CustomerID 
JOIN OrderItems ON Orders.OrderID = OrderItems.OrderID 
GROUP BY EmailAddress, ItemPrice, Quantity 
ORDER BY TotalSum DESC; 

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

+0

Я пытался группировать только по адресу электронной почты, и я получил ошибки о том, что «ItemPrice» и «Количество» были признаны недействительными в списке выбора, потому что они не содержатся ни в агрегатной функции или предложения GROUP BY. Каково решение этого вопроса, не включив их в предложение Group By? – Scarlet

ответ

0

Причина, по которой вы получаете несколько строк, состоит в том, что вы группируете три разных столбца: электронную почту, цену товара и количество. Если одно и то же письмо появляется дважды, но цена товара для каждого отличается, чем возвращать несколько строк. Это потому, что SQL сначала группируется по электронной почте, затем группируется по цене товара, а затем количеству. Любые строки с другой комбинацией этих 3 будут рассматриваться как их собственная группа.

Если вам нужна одна строка для каждого клиента, просто ограничьте свою группу на адрес электронной почты. Это вернет электронную почту клиента, а также общую сумму всех их покупок и общие скидки для этого клиента.

EDIT Я считаю, что ошибка, которую вы получаете, заключается в том, что вы пытаетесь суммировать цену товара для всех строк, а затем умножать ее на одну величину. Вы можете логически понять, почему это не имеет смысла, если вы пытаетесь сгруппировать их. Я считаю, что лучший способ справиться с этим - сделать подзапрос, который выбирает все строки и возвращает адрес электронной почты, сумму и скидку. Когда у вас есть этот подзапрос, вы можете сгруппировать его после.

Попробуйте это в качестве подзапроса:

SELECT EmailAddress, ItemPrice * Quantity AS orderSum, DiscountAmount * Quantity AS discount 
FROM customers 
    JOIN orders ON customers.customerid = orders.customerid 
    JOIN orderitems ON orders.orderid = orderitems.orderid 

Если это поможет вам запустить этот первый визуализировать то, что это возвращается, идти вперед. Это возвращает все отдельные строки с требуемой информацией. Все, что осталось, это группировать и суммировать их:

SELECT EmailAddress, SUM(orderSum) AS totalSum, SUM(discount) AS totalDiscount 
FROM (
    SELECT EmailAddress, ItemPrice * Quantity AS orderSum, DiscountAmount * Quantity AS discount 
    FROM customers 
     JOIN orders ON customers.customerid = orders.customerid 
     JOIN orderitems ON orders.orderid = orderitems.orderid 
    ) t 
GROUP BY EmailAddress 
ORDER BY totalSum DESC 
2

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

SELECT 
    EmailAddress, 
    SUM(ItemPrice * Quantity) AS TotalSum, 
    SUM(DiscountAmount * Quantity) AS TotalDiscount 
FROM Customers 
    JOIN Orders 
     ON Customers.CustomerID = Orders.CustomerID 
    JOIN OrderItems 
     ON Orders.OrderID = OrderItems.OrderID 
GROUP BY EmailAddress 
ORDER BY TotalSum DESC; 
+0

Да, спасибо! Это было именно то, что мне нужно. Таким образом, это было просто() no в нужном месте в предложении select, которое давало мне ошибки. Большой! – Scarlet

+0

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

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