-1

我有那两张桌子

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 是两个表之间的键,我不能修改那些表,我想要的是查询每个事务在队列中花费的时间量

当每个表中有一个项目时很容易,但是当项目多次排队时,我该如何计算呢?

4

3 回答 3

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 和输入日期获得一个行号,然后您可以同时加入行号和 transID 以停止任何交叉加入。

SQL Fiddle 示例

于 2013-01-21T20:04:15.857 回答
0

答案2:在您发表评论之后。(作为旁注,您的某些日期15/1/2013不代表13/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
于 2013-01-21T16:49:25.797 回答
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 结束时的那个定义,UNIT_TIMESTAMP 会抛出毫秒,你需要花费几天 - 或者你想要的任何东西。

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

于 2013-01-21T17:15:21.750 回答