Для сравнения заказов без учета поставщиков или строк заказа:
/* query 1 */
SELECT
COUNT(*) AS ordercount
FROM Sales.Orders AS o
WHERE o.OrderDate >= '20150101' AND o.OrderDate < '20160101'
Затем для сравнения строк заказов без учета поставщиков:
/* query 2 */
SELECT
COUNT(DISTINCT o.OrderID) AS ordercount
, SUM(olp.Quantity * olp.UnitPrice) AS sales
FROM Sales.Orders AS o
INNER JOIN Sales.OrderLines AS olp ON olP.OrderID = o.OrderID
WHERE o.OrderDate >= '20150101' AND o.OrderDate < '20160101'
Теперь начните вводить большеобъединяет, и если значения изменяются, то ошибается самое последнее объединение:
/* query 3 */
SELECT
COUNT(DISTINCT o.OrderID) AS ordercount
, SUM(olp.Quantity * olp.UnitPrice) AS sales
FROM Sales.Orders AS o
INNER JOIN Sales.OrderLines AS olp ON olP.OrderID = o.OrderID
INNER JOIN Warehouse.StockItems AS w ON w.StockItemID = olp.StockItemID
WHERE o.OrderDate >= '20150101' AND o.OrderDate < '20160101'
, а затем:
/* query 4 */
SELECT
COUNT(DISTINCT o.OrderID) AS ordercount
, SUM(olp.Quantity * olp.UnitPrice) AS sales
FROM Sales.Orders AS o
INNER JOIN Sales.OrderLines AS olp ON olP.OrderID = o.OrderID
INNER JOIN Warehouse.StockItems AS w ON w.StockItemID = olp.StockItemID
INNER JOIN Purchasing.Suppliers s ON s.SupplierID = w.SupplierID
WHERE o.OrderDate >= '20150101' AND o.OrderDate < '20160101'
Вам определенно не нужно соединять строки заказа дважды, что касаетсяприсоединение слева зависит от того, чего вы пытаетесь достичь, например:
Только поставщики с заказами в диапазоне дат:
/* query 5 */
SELECT
s.SupplierID
, s.SupplierName
, COUNT(DISTINCT o.OrderID) AS ordercount
, ISNULL(SUM(olp.Quantity * olp.UnitPrice), 0.00) AS sales
FROM Purchasing.Suppliers s
INNER JOIN Warehouse.StockItems AS w ON s.SupplierID = w.SupplierID
INNER JOIN Sales.OrderLines AS olp ON w.StockItemID = olp.StockItemID
INNER JOIN Sales.Orders AS o ON olP.OrderID = o.OrderID
WHERE o.OrderDate >= '20150101'
AND o.OrderDate < '20160101' -- note: this is "the next" day
GROUP BY
s.SupplierID
, s.SupplierName
ORDER BY
sales DESC
, ordercount
, SupplierName;
Все поставщики со ссылками на запасы:
/* query 6 */
SELECT
s.SupplierID
, s.SupplierName
, COUNT(DISTINCT o.OrderID) AS ordercount
, ISNULL(SUM(olp.Quantity * olp.UnitPrice), 0.00) AS sales
FROM Purchasing.Suppliers s
INNER JOIN Warehouse.StockItems AS w ON s.SupplierID = w.SupplierID
LEFT JOIN Sales.OrderLines AS olp ON w.StockItemID = olp.StockItemID
LEFT JOIN Sales.Orders AS o ON olP.OrderID = o.OrderID
AND o.OrderDate >= '20150101'
AND o.OrderDate < '20160101' -- note: this is "the next" day
GROUP BY
s.SupplierID
, s.SupplierName
ORDER BY
sales DESC
, ordercount
, SupplierName;
Каждый поставщик:
/* query 7 */
SELECT
s.SupplierID
, s.SupplierName
, COUNT(DISTINCT o.OrderID) AS ordercount
, ISNULL(SUM(olp.Quantity * olp.UnitPrice), 0.00) AS sales
FROM Purchasing.Suppliers s
LEFT JOIN Warehouse.StockItems AS w ON s.SupplierID = w.SupplierID
LEFT JOIN Sales.OrderLines AS olp ON w.StockItemID = olp.StockItemID
LEFT JOIN Sales.Orders AS o ON olP.OrderID = o.OrderID
AND o.OrderDate >= '20150101'
AND o.OrderDate < '20160101' -- note: this is "the next" day
GROUP BY
s.SupplierID
, s.SupplierName
ORDER BY
sales DESC
, ordercount
, SupplierName;
Пожалуйста, будьте очень осторожны с использованием between
для диапазонов дат. Самый надежный способ определить диапазон дат - это использовать >=
и <
как показано выше, таким образом, не имеет значения, какова точность данных во времени.Также YYYYMMDD - самый безопасный формат литералов даты в TSQL.