簡體   English   中英

SQL Server 最大日期時間

[英]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, OrderIDOrders應該有一個以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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM