两桌之间的Datediff

时间:2013-01-21 16:38:33

标签: sql sql-server tsql

我有这两张桌子

1 - 添加到队列表

TransID , ADD date 
10 , 10/10/2012
11 , 14/10/2012
11 , 18/11/2012
11 , 25/12/2012
12 , 1/1/2013

2 - 从队列表中删除

TransID , Removed Date 
10 , 15/1/2013
11 , 12/12/2012
11 , 13/1/2013
11 , 20/1/2013

TansID是两个表之间的关键,我不能修改那些表,我想要的是查询每个事务在队列中花费的时间

当每个表中有一个项目时很容易,但是当项目排队不止一次时,我该怎么计算?

3 个答案:

答案 0 :(得分:1)

假设订单TransID输入到Add表中的顺序与删除顺序相同,您可以使用以下命令:

WITH OrderedAdds AS
(   SELECT  TransID,
            AddDate,
            [RowNumber] = ROW_NUMBER() OVER(PARTITION BY TransID ORDER BY AddDate)
    FROM    AddTable
), OrderedRemoves AS
(   SELECT  TransID,
            RemovedDate,
            [RowNumber] = ROW_NUMBER() OVER(PARTITION BY TransID ORDER BY RemovedDate)
    FROM    RemoveTable
)
SELECT  OrderedAdds.TransID,
        OrderedAdds.AddDate,
        OrderedRemoves.RemovedDate,
        [DaysInQueue] = DATEDIFF(DAY, OrderedAdds.AddDate, ISNULL(OrderedRemoves.RemovedDate, CURRENT_TIMESTAMP))
FROM    OrderedAdds
        LEFT JOIN OrderedRemoves
            ON OrderedAdds.TransID = OrderedRemoves.TransID
            AND OrderedAdds.RowNumber = OrderedRemoves.RowNumber;

关键部分是每条记录根据交易ID和输入日期得到一个rownumber,然后你可以加入rownumber和transID来阻止任何交叉加入。

<强> Example on SQL Fiddle

答案 1 :(得分:0)

答案2:在您的评论之后。 (另请注意,您的部分日期15/1/201313/1/2013不代表正确的日期格式)

select transId, sum(numberOfDays) totalQueueTime
from (
    select a.transId,
       datediff(day,a.addDate,isnull(r.removeDate,a.addDate)) numberOfDays
    from AddTable a left join RemoveTable r on a.transId = r.transId
    order by a.transId, a.addDate, r.removeDate
) X
group by transId

答案1:在你的评论之前

假设除非删除新记录,否则不会添加新记录。另请注意,以下查询会带来numberOfDays as zero for unremoved records;

select a.transId, a.addDate, r.removeDate,
       datediff(day,a.addDate,isnull(r.removeDate,a.addDate)) numberOfDays
from AddTable a left join RemoveTable r on a.transId = r.transId
order by a.transId, a.addDate, r.removeDate

答案 2 :(得分:0)

免责声明:这可能存在问题,但我希望向您发送一个可能的方向。确保遇到问题。

您可以按以下方向尝试(根据您的系统,版本等,可能会以某种方式工作):

SELECT transId, (sum(add_date_sum) - sum(remove_date_sum)) / (1000*60*60*24)
FROM
(
    SELECT transId, (SUM(UNIX_TIMESTAMP(add_date)) as add_date_sum, 0 as remove_date_sum
    FROM add_to_queue 
    GROUP BY transId

    UNION ALL

    SELECT transId, 0 as add_date_sum, (SUM(UNIX_TIMESTAMP(remove_date)) as remove_date_sum
    FROM remove_from_queue 
    GROUP BY transId
)
GROUP BY transId;

一点解释:据我所知,你不能总结日期,但你可以将它们转换为某种时间戳。检查UNIX_TIMESTAMPS是否适合您,或者找出其他内容。然后你可以在每个表中求和,通过方便地将另一个作为zeto创建联合,然后减去联合查询。

至于第一个SELECT结尾的那个devision,UNIT_TIMESTAMP抛出几毫秒,你可以得到几天 - 或者你想要的任何东西。

这一切都说 - 我可能会使用存储过程或一些客户端脚本来解决这个问题。 SQL不是每场战斗的武器。制作两个单独的查询可以更简单。