开发者

Get top one record of same FK on date difference

I need to get top 1 record from same customer inserted within one hour. If record is inserted after one hour then don't need that one. Please see following table. This i开发者_运维百科s just a sample of 1000s of records. I am using SQL Server 2005.

alt text http://img651.imageshack.us/img651/3990/customershavingmultiple.png


The idea is as follows

  • Select all child orders within one hour with its minimum possible (Parent)ID. (I am assuming here that the lowest OrderID will also be the oldest OrderID).
  • Join these results with the original table.
  • Use these results as the basis of the update statement.

SQL Statement

UPDATE  Orders
SET     ParentOrderID = p.ParentOrderID
FROM    Orders o
        INNER JOIN (
          SELECT  ParentOrderID = MIN(o1.OrderID), OrderID = o2.OrderID
          FROM    Orders o1
                  LEFT OUTER JOIN Orders o2 ON 
                    o2.CustomerID = o1.CustomerID
                    AND o2.OrderDate > o1.OrderDate
                    AND DATEADD(hh, -1, o2.OrderDate) < o1.OrderDate
          GROUP BY o2.OrderID
        ) p ON p.OrderID = o.OrderID


Considering the following table:

CREATE TABLE [dbo].[Orders](
    [OrderID] [int] IDENTITY(1,1) NOT NULL,
    [CustomerID] [int] NULL,
    [OrderDate] [datetime] NULL,
     CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
    (
        [OrderID] ASC
    )
)

the following statement shows the last order placed by a customer within the time frame followed by the other orders.

;With OrderList As
(
Select Top 100 Percent * From dbo.Orders
Where OrderDate >= DateAdd(hh, -1, GetDate())
Order By OrderDate Desc
)
Select 'First' As DataType, 
    CustomerID, Min(OrderID) As OrderID, Min(OrderDate) As OrderDate
From OrderList
Group By CustomerID
Union All
Select 'Second' As DataType,
    CustomerID, OrderID, OrderDate
From OrderList
Where OrderID Not In
(
    Select Min(OrderID) As OrderID
    From OrderList
    Group By CustomerID
)
--Union All
--Select 'Raw' As DataType, 
--    CustomerID, OrderID, OrderDate
--From Orders

The last part is commented out as I used it to test whether I actually got the right rows.

In short the With statement limits the orders from the table to the ones placed within the last hour based on the current system date and orders them by order date. The first statement (Select 'First') then extracts just the first orders by customer. The second statement (Select 'Second') then extracts all other orders which are not in the first statement.

This should work as you expected, Muhammed, however I don't have 1000s of rows to test this with. Performance should be ok as the With part will create a temporary table to work with.


select Top 1 * 
from (select orderid, customerid, orderdate, parentorderid from customer where customerid=@customerid)
where DATEDIFF(mi, orderdate, GETDATE()) > 60

order by orderdate

Note I have used a sub query here to filter on the customerid first so that you get better performance. You should try to avoid using functions (DATEDIFF) in a restriction clause over large sets of date

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜