[英]SQL Server max Datetime
我對 SQL Server 有點陌生,我正在嘗試執行一個非常簡單的查詢,如下所示:
SELECT
ProductID, o.OrderID, o.CustomerID, CompanyName,OrderDate, Quantity
FROM
o
JOIN
[Order Details] od on o.OrderID = od.OrderID
JOIN
Customers c on c.CustomerID = o.CustomerID
WHERE
orderdate = (select max(OrderDate)
from o
where ProductID = od.ProductID)
然后我得到了這個。
ProductID OrderID CustomerID CompanyName OrderDate Quantity
2 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 24
3 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 4
4 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 1
6 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 1
7 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 1
8 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 2
10 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 1
12 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 2
13 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 4
14 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 1
16 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 2
20 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 1
23 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 2
32 11077 RATTC Rattlesnake Canyon Grocery 1998-05-07 09:50:47.000 1
但我想獲得每個產品 ID 的最新訂單日期。 像這樣:
那么我該怎么做才能得到它?
這應該讓你開始。 我假設Order Details
具有訂單行項目。
SELECT
p.ProductID,
o.OrderID,
o.CustomerID,
o.CompanyName,
o.OrderDate
FROM
dbo.Products p
CROSS APPLY (
SELECT TOP 1 *
FROM dbo.Orders o
WHERE EXISTS (
SELECT *
FROM dbo.[Order Details] od
WHERE
o.OrderID = od.OrderID
AND p.ProductID = od.ProductID
)
ORDER BY o.OrderDate DESC
) o
INNER JOIN dbo.Customers c
ON o.CustomerID = c.CustomerID
;
我假設[Order Details]
行可以有兩次相同的OrderID
,這使得獲取Quantity
(我省略了它)變得有點復雜。 你想要這個數量的總和,還是顯示兩行? 根據您想要的結果以及該表的實施方式,這可能是您想要的解決方案:
SELECT
p.ProductID,
odq.OrderID,
odq.CustomerID,
odq.CompanyName,
odq.OrderDate,
odq.Quantity
FROM
dbo.Products p
CROSS APPLY (
SELECT TOP 1 *
FROM dbo.Orders o
CROSS APPLY (
SELECT TotalQuantity = Sum(Quantity)
FROM dbo.[Order Details] od
WHERE
o.OrderID = od.OrderID
AND p.ProductID = od.ProductID
) odq
ORDER BY o.OrderDate DESC
) odq
INNER JOIN dbo.Customers c
ON o.CustomerID = c.CustomerID
;
只要您的表上有適當的索引( Order Details
應該有索引ProductID, OrderID
和Orders
應該有一個以ProductID, OrderDate
開頭的索引) ProductID, OrderDate
這個查詢應該會執行得很好。 隨着系統數據的增長,其性能應該保持穩定。
我確實假設您有一個dbo.Products
表,並且通過從CROSS APPLY
更改為OUTER APPLY
(第一個),您可以顯示沒有訂單的產品。 或者,還有另一個可能的查詢:
WITH OrderSequences AS (
SELECT
Sequence = Rank() OVER (PARTITION BY od.ProductID ORDER BY o.OrderDate DESC),
o.*,
od.ProductID,
od.Quantity
FROM
dbo.Orders o
INNER JOIN dbo.[Order Details] od
ON o.OrderID = od.OrderID
)
SELECT
o.OrderID,
o.CustomerID,
o.CompanyName,
o.OrderDate,
o.ProductID,
o.Quantity
FROM
OrderSequences o
INNER JOIN dbo.Customers c
ON o.CustomerID = c.CustomerID
WHERE
Sequence = 1
;
同樣,如果您可以在一個OrderID
的多個行上使用相同的OrderID
(在我看來這很可能),那么您將需要進行某種求和,或容忍這將生成的重復行(如如果它們是最后一次訂購 ProductID 時,它將以相同的順序顯示兩行)。
隨着系統老化和數據積累,這第二個查詢可能會變得越來越慢,因為它被迫對整個表中的每一行執行加窗函數(它永遠無法確定它找到了最高日期,並且找到了每個ProductID
直到結束)。
WITH X AS
(SELECT ProductID
, o.OrderID
, o.CustomerID
, CompanyName
,OrderDate
, Quantity
,ROW_NUMBER() OVER (PARTITION BY od.productid ORDER BY o.OrderDate DESC) rn
FROM [Orders] o
JOIN [Order Details] od on o.OrderID = od.OrderID
join Customers c on c.CustomerID=o.CustomerID
)
SELECT ProductID
, OrderID
, CustomerID
, CompanyName
, OrderDate
, Quantity
FROM X
WHERE rn = 1
或者
SELECT ProductID
, OrderID
, CustomerID
, CompanyName
, OrderDate
, Quantity
FROM
(SELECT ProductID
, o.OrderID
, o.CustomerID
, CompanyName
,OrderDate
, Quantity
,ROW_NUMBER() OVER (PARTITION BY od.productid ORDER BY o.OrderDate DESC) rn
FROM [Orders] o
JOIN [Order Details] od on o.OrderID = od.OrderID
join Customers c on c.CustomerID=o.CustomerID
)x
WHERE rn = 1
在子查詢中使用MAX(OrderDate)
,沒有什么可以將 max(date) 與父查詢中的 productID 關聯起來。 因此,您將始終從 Order-Product 連接中獲得具有第一個ProductID 的 Max(Date) 的所有訂單。
執行這種過濾器的最佳方法是將o
order 表加入到自身中。
SELECT ProductID, o.OrderID, o.CustomerID, CompanyName,OrderDate, Quantity
FROM o
LEFT JOIN o2 ON o.ProductID = o2.ProductID AND o2.OrderDate > o.OrderDate
JOIN [Order Details] od on o.OrderID = od.OrderID
join Customers c on c.CustomerID=o.CustomerID
WHERE o2.OrderDate IS NULL
所以在這里我們將一個產品的所有訂單與具有更大 OrderDate 的同一產品的所有其他訂單連接起來,然后過濾沒有更大訂單日期的訂單,以便o.OrderDate
將是MAX(OrderDate)
每個產品ID
(免責聲明:上述 SQL 未經測試,可能需要修改才能在您的數據庫上正常運行,但該想法應該適合您的需要。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.