2013-01-21 40 views
-1

我有这两个表的DATEDIFF之间的两个

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

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

+0

我不认为你的数据模型将支持这样的查询。将无法确定哪个ADD与哪个REMOVE相关联。 – paul

+0

在上面的例子中,这个查询的结果应该是什么? – zmilojko

+0

应该最终让我像这样 TRANSID,总排队时间 10,65 11,79 - 在这种情况下,它应该得到的所有行之间的日期差异,总结他们 – Mshayeb

回答

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 
+0

我会试试 – Mshayeb

+0

第二次查询得到第一次入口和最后一次入口之间的差异,这不完全是我们想要的,因为在排队时间之间可能有工作时间,必须扣除 – Mshayeb

+0

我不是'由于OP没有这样的细节,所以一定要确定。我已经更新了答案2。现在试试。 – Kaf

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不是每场战斗的武器。做两个单独的查询可以简单得多。

+0

它认为它会工作,如果我有MYSQL,但即时通讯工作在MSSQL – Mshayeb

+0

不错,你提到现在......只有一个SQL标签。无论哪种方式,UNION查询应该在任何地方工作,所以你可以找出MSSQL中的UNIX_TIMESTAMP类似的函数... – zmilojko

1

假设顺序TransIDs输入到添加表是删除它们的顺序相同,您可以使用以下命令:

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