Datediff需要用于多行订单活动

时间:2013-11-04 23:18:36

标签: sql tsql datediff

在SQL Server(TSQL)中,我需要找到一系列订单活动之间的日期差异:

tblOrderActivity
OrderID  ActivityID  ActivityDate
1        1           4/16/2007 8:34:00 AM
1        2           4/16/2007 9:22:00 AM
2        1           4/16/2007 8:34:00 AM
3        1           4/16/2007 8:34:00 AM
3        2           4/16/2007 9:22:00 AM
4        1           4/16/2007 8:34:00 AM
4        2           4/16/2007 9:22:00 AM

无论如何......我知道DATEDIFF。所以我目前的尝试看起来像:

Select DATEDIFF( MI,
    (select tblOrderActivity.ActivityDate 
        from tblOrderActivity
        where ActivityID = 1), 
    (select tblOrderActivity.ActivityDate
        from tblOrderActivity
        where ActivityID = 2) ) 

如果我添加AND OrderID = 1或特定号码,此代码实际上有效。问题是......它需要适用于所有订单。因此它应该将orderID作为一列返回,并将ActivityID = 2的日期从Activity = 1的日期中减去。所以对于Order 1,3和4,它应该有48分钟。对于订单2,因为没有活动2,那里应该没有结果(我猜是NULL?)。

编辑:

好的,我正在遇到另一个问题。所以这是“完整”表。每个订单有两个以上的活动。

tblOrderActivity
OrderID  ActivityID  ActivityDate
1        1           4/16/2007 8:34:00 AM
1        2           4/16/2007 9:22:00 AM
1        3           4/16/2007 9:51:00 AM
1        4           4/16/2007 4:14:00 PM
2        1           4/16/2007 8:34:00 AM
3        1           4/16/2007 8:34:00 AM
3        2           4/16/2007 9:22:00 AM

这是我目前的代码:

    SELECT
t1.OrderID,
DATEDIFF(MI, t1.ActivityDate, t2.ActivityDate) as TurnTime1,
DATEDIFF(MI, t2.ActivityDate, t3.ActivityDate) as TurnTime2,
DATEDIFF(MI, t3.ActivityDate, t4.ActivityDate) as TurnTime3,
DATEDIFF(MI, t1.ActivityDate, t4.ActivityDate) as TurnTime4 
FROM tblOrderActivity t1 INNER JOIN tblOrderActivity t2 ON t1.OrderID = t2.OrderID INNER JOIN tblOrderActivity t3 ON t2.OrderID = t3.OrderID INNER JOIN tblOrderActivity t4 ON t3.OrderID = t4.OrderID WHERE t1.ActivityID = 1 AND t2.ActivityID = 2 AND t3.ActivityID = 3 AND t4.ActivityID = 4 

叹息......我似乎不擅长格式化代码块。我道歉。

无论如何。当我运行这个代码时,它只给我订单1,然后转时间1,2,3,4等。它没有给我其他2个订单,因为(我假设)他们没有全部4项活动。

有没有办法解释这个?

2 个答案:

答案 0 :(得分:0)

假设您只想要ActivityID = 1和ActivityID = 2之间的差异,而且只有两个活动中只有一个的订单没有行:

SELECT
    t1.OrderID,
    DATEDIFF(MI, t1.ActivityDate, t2.ActivityDate)
FROM tblOrderActivity t1
INNER JOIN tblOrderActivity t2 ON t1.OrderID = t2.OrderID
WHERE t1.ActivityID = 1 AND t2.ActivityID = 2

答案 1 :(得分:0)

这里有两个问题:

首先,您正在使用内部联接。内部联接指定如果在两个表中都找不到结果值,则不返回任何内容。如果您将所有内部联接更改为左外部联接,这将解决您的一半问题, 但不是全部问题!

其次,您要在Where子句中指定每个ActivityID值。这意味着它正在查看每个ActivityID条目,并且仅当它等于1,2,3, 4时才包含它,这将永远不会发生。相反,您应该在连接本身中指定这些条件,如下所示:

Select ...
From tblOrderActivity t1
    Left Outer Join tblOrderActivity t2
        on t1.OrderID = t2.OrderID
            and t2.OrderID = 2
    Left Outer Join tblOrderActivity t3
        on t1.OrderID = t3.OrderID
            and t3.OrderID = 3
    Left Outer Join tblOrderActivity t4
        on t1.OrderID = t4.OrderID
            and t4.OrderID = 4

Where t1.OrderID = 1

你想在where子句中指定t1.OrderID等于1,因为从你的帖子中, 总是 应该是真的。请记住,对Where子句的整体评估必须始终为真。因此,您可以更改为左外连接但不更改您的Where标准,但它仍然无效。您可以更改您的位置标准,但不能更改您的联接,它将无法正常工作。你必须改变它们!

希望这有帮助!