我有这两张桌子
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 :(得分: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/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
答案 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不是每场战斗的武器。制作两个单独的查询可以更简单。