减去涉及多个连接的日期

Subtracting Dates with multiple Joins Involved

我希望有人能帮助我。

我有以下 5 个表:

tblCustomer

CustomerID   CustomerName   
 -------     ------------
   1         ABC Bank     
   2         Chase Bank      

tblOrderType

OrderTypeID    OrderTypeName   
 ----------    ------------
   1           Assignment     
   2           LienRelease  

tblActivity

ActivityID        ActivityName   
 ----------       ------------
   1              Received     
   2              Keyed
   3              Printed
   4              Delivered To Customer

tblOrder

OrderID        CustomerID      OrderTypeID   LoanNumber
 ----------    ------------    -----------   ----------
   1           1                1            45584565
   2           1                1            45566856
   3           1                1            45565584
   4           1                1            45588545

tblOrderActivity

OrderID        ActivityID    ActivityDate
 ----------    -----------   ----------
   1           1             2007-04-16 8:34:00 AM
   1           2             2007-04-16 9:22:00 AM  
   1           3             2007-04-16 9:51:00 AM 
   1           4             2007-04-16 4:14:00 PM  
   2           1             2007-04-16 8:34:00 AM
   2           3             2014-12-16 10:33:09 AM
   3           1             2007-04-16 8:34:00 AM
   3           2             2007-04-16 9:22:00 AM
   3           3             2007-04-16 9:51:00 AM
   3           4             2007-04-16 4:14:00 PM
   4           1             2007-04-16 8:34:00 AM
   4           2             2007-04-16 9:22:00 AM
   4           3             2007-04-16 9:51:00 AM 

出于保护目的,信息已更改。所以说我需要能够列出客户的所有订单和时差(以分钟为单位): -“接收”到“键控”为 [TurnTime1] -“键入”到“打印”为 [TurnTime2] -“打印”到“交付”为 [TurnTime3] -“已接收”到“已交付”为 [TurnTime4] 我还需要 return CustomerName、OrderTypeName、LoanNumber、TurnTime1、TurnTime2、TurnTime3 和 TurnTime4。我相信我很接近,但是,我尝试了两种不同的方法来做到这一点,这两种方法都不正确,我被卡住了。第一个选项仅包含 4 行,每个 TurnTime 列的值为“0”。第二个选项包括 600 多行。我相信这应该是 return 只有 11 行数据和一些数据不符合规定的额外行。这是我目前所拥有的:

选项 1

SELECT DISTINCT tblCustomer.CustomerName, tblOrderType.OrderTypeName, tblOrder.LoanNumber,
(DATEPART(mi,(tblOrderActivity.ActivityDate - tblOrderActivity.ActivityDate))) AS [TurnTime1],
(DATEPART(mi,(tblOrderActivity.ActivityDate - tblOrderActivity.ActivityDate))) AS [TurnTime2],
(DATEPART(mi,(tblOrderActivity.ActivityDate - tblOrderActivity.ActivityDate))) AS [TurnTime3],
(DATEPART(mi,(tblOrderActivity.ActivityDate - tblOrderActivity.ActivityDate))) AS [TurnTime4]
FROM tblOrder
INNER JOIN tblOrderActivity
ON tblOrder.OrderID = tblOrderActivity.OrderID
INNER JOIN tblActivity
ON tblOrderActivity.ActivityID = tblActivity.ActivityID
INNER JOIN tblOrderType
ON tblOrderType.OrderTypeID = tblOrder.OrderTypeID
INNER JOIN tblCustomer
ON tblCustomer.CustomerID = tblOrder.CustomerID
WHERE EXISTS (SELECT * FROM tblActivity WHERE ActivityName IS NOT NULL)
GROUP BY tblCustomer.CustomerName, tblOrderType.OrderTypeName, tblorder.LoanNumber, tblOrderActivity.ActivityDate;

选项 2

SELECT DISTINCT tblCustomer.CustomerName, tblOrderType.OrderTypeName, tblOrder.LoanNumber,
(DATEPART(mi,(TT2.ActivityDate - TT1.ActivityDate))) AS [TurnTime1],
(DATEPART(mi,(TT3.ActivityDate - TT2.ActivityDate))) AS [TurnTime2],
(DATEPART(mi,(TT4.ActivityDate - TT3.ActivityDate))) AS [TurnTime3],
(DATEPART(mi,(TT4.ActivityDate - TT1.ActivityDate))) AS [TurnTime4]
FROM tblOrder
INNER JOIN tblOrderActivity AS TT1
ON tblOrder.OrderID = TT1.OrderID
INNER JOIN tblOrderActivity AS TT2
ON tblOrder.OrderID = TT2.OrderID
INNER JOIN tblOrderActivity AS TT3
ON tblOrder.OrderID = TT3.OrderID
INNER JOIN tblOrderActivity AS TT4
ON tblOrder.OrderID = TT4.OrderID
INNER JOIN tblActivity AS TA1
ON TT1.ActivityID = TA1.ActivityID
INNER JOIN tblActivity AS TA2
ON TT2.ActivityID = TA2.ActivityID
INNER JOIN tblActivity AS TA3
ON TT3.ActivityID = TA3.ActivityID
INNER JOIN tblActivity AS TA4
ON TT4.ActivityID = TA4.ActivityID
INNER JOIN tblOrderType
ON tblOrderType.OrderTypeID = tblOrder.OrderTypeID
INNER JOIN tblCustomer
ON tblCustomer.CustomerID = tblOrder.CustomerID
WHERE EXISTS (SELECT * FROM tblActivity WHERE ActivityName IS NOT NULL)
GROUP BY tblCustomer.CustomerName, tblOrderType.OrderTypeName, tblorder.LoanNumber, TT1.ActivityDate,
TT2.ActivityDate, TT3.ActivityDate, TT4.ActivityDate;

SQL Fiddle Demo

您可以使用 case based aggregation 和减法来计算客户每个订单的活动之间的时间差。

select C.CustomerNAme, OT.OrderTypeName, O.LoanNumber, 
      max ( case when OA.ActivityID =2 then datediff(minute,0,OA.ActivityDate) end)  - 
      max ( case When OA.ActivityID =1 then datediff(minute,0,OA.ActivityDate) end) as TurnTime1,
      max ( case when OA.ActivityID =3 then datediff(minute,0,OA.ActivityDate) end)  - 
      max ( case When OA.ActivityID =2 then datediff(minute,0,OA.ActivityDate) end) as TurnTime2,
      max ( case when OA.ActivityID =4 then datediff(minute,0,OA.ActivityDate) end)  - 
      max ( case When OA.ActivityID =3 then datediff(minute,0,OA.ActivityDate) end) as TurnTime3,
      max ( case when OA.ActivityID =4 then datediff(minute,0,OA.ActivityDate) end)  - 
      max ( case When OA.ActivityID =1 then datediff(minute,0,OA.ActivityDate) end) as TurnTime4


FROM tblCustomer C
JOIN tblOrder O
on C.CustomerID = O.CustomerID
JOIN tblOrderActivity OA
on OA.OrderID = O.OrderID
JOIN tblOrderType OT
on OT.OrderTypeID = O.OrderTypeID
GROUP BY C.CustomerName, OT.OrderTypeName, O.LoanNumber

这应该只是一个简单的问题,即根据 table activity 为您想要的每个组创建一个连接 table。请注意,尽管我假设 activity 只能执行一次。

Select tblCustomer.CustomerName, 
       tblOrderType.OrderTypeName, 
       tblOrder.LoanNumber,
       DATEDiff(mi,tblOrderReceived.ActivityDate, tblOrderKeyed.ActivityDate) AS [TurnTime1],
       DATEDiff(mi,tblOrderKeyed.ActivityDate, tblOrderPrinted.ActivityDate) AS [TurnTime2],
       DATEDiff(mi,tblOrderPrinted.ActivityDate, tblOrderDelivered.ActivityDate) AS [TurnTime3],
       DATEDiff(mi,tblOrderReceived.ActivityDate, tblOrderDelivered.ActivityDate) AS [TurnTime4]
From tblOrder
    INNER JOIN tblOrderType
        ON tblOrderType.OrderTypeID = tblOrder.OrderTypeID
    INNER JOIN tblCustomer
        ON tblCustomer.CustomerID = tblOrder.CustomerID
    Left Outer Join tblOrderActivity tblOrderReceived
        ON tblOrder.OrderID = tblOrderActivity.OrderID
    Left Outer Join tblOrderActivity tblOrderKeyed
        ON tblOrder.OrderID = tblOrderActivity.OrderID
    Left Outer Join tblOrderActivity tblOrderPrinted
        ON tblOrder.OrderID = tblOrderActivity.OrderID
    Left Outer Join tblOrderActivity tblOrderDelivered
        ON tblOrder.OrderID = tblOrderActivity.OrderID
    Left Outer Join tblActivity
        ON tblOrderReceived.ActivityID = tblActivity.ActivityID
            OR tblOrderKeyed.ActivityID = tblActivity.ActivityID
            OR tblOrderPrinted.ActivityID = tblActivity.ActivityID
            OR tblOrderDelivered.ActivityID = tblActivity.ActivityID
Where tblOrderReceived.ActivityID = 1
    And tblOrderKeyed.ActivityID = 2
    And tblOrderPrinted.ActivityID = 3
    And tblOrderDelivered.ActivityID = 4
    And tblOrder.OrderID In (Select ActivityMask.OrderID from tblOrderActivity ActivityMask)

这个怎么样: SQL Fiddle

MS SQL Server 2008 架构设置:

create table tblCustomer
(
    CustomerID int,
    CustomerName varchar(max)
)
INSERT INTO tblCustomer
VALUES
(  1, 'ABC Bank'),
(  2, 'Chase Bank')

create table tblOrderType
(
    OrderTypeID int,
    OrderTypeName varchar(max)
)

INSERT INTO tblOrderType
VALUES
(  1, 'Assignment'),
(  2, 'LienRelease')


create table tblActivity
(
    ActivityID int,
    ActivityName varchar(max)
)

INSERT INTO tblActivity
VALUES
(  1, 'Received'),
(  2, 'Keyed'),
(  3, 'Printed'),
(  4, 'Delivered To Customer')

CREATE TABLE tblOrder
(
    OrderID int,
    CustomerID int,
    OrderTypeID int,
    LoanNumber int
)

INSERT INTO tblOrder
VALUES
(  1, 1, 1, 45584565),
(  2, 1, 1, 45566856),
(  3, 1, 1, 45565584),
(  4, 1, 1, 45588545)

CREATE TABLE tblOrderActivity
(
    OrderID int,
    ActivityID int,
    ActivityDate DateTime
)

INSERT INTO tblOrderActivity
VALUES
(1, 1, '2007-04-16 8:34:00 AM'),
(1, 2, '2007-04-16 9:22:00 AM'),  
(1, 3, '2007-04-16 9:51:00 AM'), 
(1, 4, '2007-04-16 4:14:00 PM'),  
(2, 1, '2007-04-16 8:34:00 AM'),
(2, 3, '2014-12-16 10:33:09 AM'),
(3, 1, '2007-04-16 8:34:00 AM'),
(3, 2, '2007-04-16 9:22:00 AM'),
(3, 3, '2007-04-16 9:51:00 AM'),
(3, 4, '2007-04-16 4:14:00 PM'),
(4, 1, '2007-04-16 8:34:00 AM'),
(4, 2, '2007-04-16 9:22:00 AM'),
(4, 3, '2007-04-16 9:51:00 AM') 

查询 1:

SELECT C.CustomerName,O.OrderId, OT.OrderTypeName, O.LoanNumber,
(DATEDIFF(mi, Received.ActivityDate, Keyed.ActivityDate)) AS [TurnTime1],
(DATEDIFF(mi, Keyed.ActivityDate, Printed.ActivityDate)) AS [TurnTime2],
(DATEDIFF(mi, Printed.ActivityDate, Delivered.ActivityDate)) AS [TurnTime3],
(DATEDIFF(mi, Received.ActivityDate, Delivered.ActivityDate)) AS [TurnTime4]
FROM tblCustomer C
INNER JOIN tblOrder O
    ON O.CustomerId = C.CustomerId
INNER JOIN tblOrderType OT
    ON OT.OrderTypeID = O.OrderTypeID
INNER JOIN tblOrderActivity Received
    ON Received.OrderID = O.OrderID AND Received.ActivityId = 1
LEFT JOIN tblOrderActivity Keyed
    ON Keyed.OrderID = O.OrderID AND Keyed.ActivityId = 2
LEFT JOIN tblOrderActivity Printed
    ON Printed.OrderID = O.OrderID AND Printed.ActivityId = 3
LEFT JOIN tblOrderActivity Delivered
    ON Delivered.OrderID = O.OrderID AND Delivered.ActivityId = 4

Results:

| CUSTOMERNAME | ORDERID | ORDERTYPENAME | LOANNUMBER | TURNTIME1 | TURNTIME2 | TURNTIME3 | TURNTIME4 |
|--------------|---------|---------------|------------|-----------|-----------|-----------|-----------|
|     ABC Bank |       1 |    Assignment |   45584565 |        48 |        29 |       383 |       460 |
|     ABC Bank |       2 |    Assignment |   45566856 |    (null) |    (null) |    (null) |    (null) |
|     ABC Bank |       3 |    Assignment |   45565584 |        48 |        29 |       383 |       460 |
|     ABC Bank |       4 |    Assignment |   45588545 |        48 |        29 |    (null) |    (null) |

如需剔除NULL行,只需将LEFT JOIN改为INNER JOIN

即可