Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Составление SQL-запросов > [MSSQL'05]Оптимизация запроса с временной таблицей


Автор: Dogo 12.8.2008, 18:26
ЗАДАЧА: 
Получить список заказчиков, которые сделали < 3х заказов.

ДИАГРАММА БД:
user posted image

МОЕ РЕШЕНИЕ:
Код

SELECT DISTINCT c.FirstName, c.LastName, o.OrderID 
INTO #Tmp
FROM Customers c
JOIN Orders o
    ON o.CustomerID = c.CustomerID
GROUP BY  c.FirstName, c.LastName, o.OrderID
ORDER BY c.LastName

SELECT FirstName + ' ' + LastName AS CustomerName, COUNT(OrderID) AS OdersNumber
FROM #Tmp
GROUP BY FirstName, LastName
HAVING COUNT(OrderID) < 3

DROP TABLE #Tmp


Подскажите, есть ли возможность оптимизировать запрос? Переписать его с использованием связанного подзапроса? 


Автор: Akina 12.8.2008, 18:33
А что,
Код

SELECT FirstName + ' ' + LastName AS CustomerName, COUNT(OrderID) AS OrdersNumber
FROM Customers c
JOIN Orders o
  ON o.CustomerID = c.CustomerID
GROUP BY CustomerName
HAVING OrdersNumber < 3

не работает, что ли?

Автор: Dogo 12.8.2008, 19:34
Нет, так работать не будет.
Один заказ может включать несколько типов Product => будет занимать несколько строк.
В следствии чего агрегирующая функция COUNT вернет не то что от нее требуется.
Ниже привел возможный вариант таблицы Orders

Код

OrderID     CustomerID  ProductID   Quantity    OrderDate
----------- ----------- ----------- ----------- -----------------------
1           1           1           1           1999-01-01 00:00:00
1           1           9           1           1999-01-01 00:00:00
2           2           3           1           1999-02-02 00:00:00
2           2           6           1           1999-02-02 00:00:00
2           2           8           3           1999-02-02 00:00:00
2           2           9           1           1999-02-02 00:00:00
3           1           4           1           2003-05-02 00:00:00
4           5           1           1           2001-01-01 00:00:00
4           5           2           1           2003-02-01 00:00:00
5           4           3           3           2008-05-02 00:00:00

Автор: skyboy 12.8.2008, 19:56
Цитата(Dogo @  12.8.2008,  18:34 Найти цитируемый пост)
Один заказ может включать несколько типов Product => будет занимать несколько строк.

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

Автор: Dogo 12.8.2008, 20:09
Я создал эту тему не для того чтобы оптимизировать структуру БД(в данном случае это сделать нельзя). 
А для того чтобы оптимизировать запрос, то есть я хочу узнать можно ли его переписать с использованием связанного подзапроса.
На мой взгляд, сделать это нельзя, но т.к. опыт работы с БД у меня небольшой, я решил задать вопрос опытным людям.

Автор: Akina 12.8.2008, 21:58
Цитата(Dogo @  12.8.2008,  20:34 Найти цитируемый пост)
Один заказ может включать несколько типов Product => будет занимать несколько строк.

В таблице Orders??? афигеть... ну ладно...
Код

SELECT FirstName + ' ' + LastName AS CustomerName, COUNT(OrderID) AS OrdersNumber
FROM Customers c
JOIN 
( SELECT DISTINCT OrderID, CustomerID
  FROM Orders
) o
  ON o.CustomerID = c.CustomerID
GROUP BY CustomerName
HAVING OrdersNumber < 3

Автор: Dogo 12.8.2008, 22:17
Akina, Спасибо! smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)