我的流程工具数据有两张表, 第一个表有机器ID,跳闸时间,跳闸原因
Machine ID Trip Time Trip Reason
XA-065 03-20-2014 09:40:098 ANY
XA-065 03-24-2014 18:33:040 ANY
XA-765 03-23-2014 22:16:002 ANY
XA-070 03-21-2014 15:17:023 ANY
第二个表有机器ID,开始时间。
Machine ID Start Time Operator
XA-065 03-20-2014 12:40:098 ANY
XA-065 03-24-2014 20:33:040 ANY
XA-765 03-23-2014 23:16:002 ANY
XA-070 03-21-2014 18:17:023 ANY
我要加入这两个表,所以,对于每台机器,我可以获得机器ID,跳闸时间,开始时间,然后我可以添加一个计算列来获得停机时间“开始时间 - 旅行时间” 问题是,当同一台机器启动并多次跳闸时,JOIN操作会匹配所有可能的跳闸/启动组合。这导致错误的停机时间计算。 这是My Join的结果,注意Machine XA-065会发生什么:
Machine ID Trip Time Start Time Downtime
XA-065 03-20-2014 09:40:098 03-20-2014 12:40:098 3 Hours
XA-065 03-20-2014 09:40:098 03-24-2014 20:33:040 **11 hours**
XA-065 03-24-2014 18:33:040 03-20-2014 12:40:098 **-6 Hours**
XA-065 03-24-2014 18:33:040 03-24-2014 20:33:040 2 Hours
XA-765 03-23-2014 22:16:002 03-23-2014 23:16:002 1 Hour
XA-070 03-21-2014 15:17:023 03-21-2014 18:17:023 3 Hours
因为JOIN将采用相同机器ID的所有可能组合,我得到错误的数据,11小时,-6小时的停机时间“第二和第三行”。 我怎样才能过滤JOIN操作以摆脱这种情况? 我按降序对这两个表进行了排序,因此,正确的值排在第一位,但我仍然得到错误的JOINED行。
非常感谢您的帮助。 A.A
答案 0 :(得分:2)
试试这个。但如果在任一表中只有一条缺失记录,结果可能会有所不同。
<强>查询强>
SELECT A.MachineID
,A.TripTime
,B.StartTime
,DATEDIFF(HOUR, A.TripTime,B.StartTime) AS DownTime
FROM
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY MachineID ORDER BY TripTime ASC) AS RN
FROM dbo.MachineTrip
) A
INNER JOIN
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY MachineID ORDER BY StartTime ASC) AS RN
FROM dbo.MachineStart
)B
ON A.MachineID = B.MachineID AND A.RN = B.RN
结果集
╔═══════════╦═════════════════════════╦═════════════════════════╦══════════╗
║ MachineID ║ TripTime ║ StartTime ║ DownTime ║
╠═══════════╬═════════════════════════╬═════════════════════════╬══════════╣
║ XA-065 ║ 2014-03-20 09:40:00.097 ║ 2014-03-20 12:40:00.097 ║ 3 ║
║ XA-065 ║ 2014-03-24 18:33:00.040 ║ 2014-03-24 20:33:00.040 ║ 2 ║
║ XA-070 ║ 2014-03-21 15:17:00.023 ║ 2014-03-21 18:17:00.023 ║ 3 ║
║ XA-765 ║ 2014-03-23 22:16:00.003 ║ 2014-03-23 23:16:00.003 ║ 1 ║
╚═══════════╩═════════════════════════╩═════════════════════════╩══════════╝
Working SQL FIDDLE
<强>建议强>
您的架构需要一些认真的关注。你应该在这两个表之间有一个外键约束,它将一个表中的记录绑定到另一个表中的记录。
或
您可以将一个表中的所有记录与一个将两个相关行绑定在一起的列和一个列(可能是一个位列)组成,该列指示记录是开始时间还是行程时间。
您的架构非常容易出错。
答案 1 :(得分:0)
您也可以通过加入和聚合来执行此操作。如果连续丢失记录或多个开始记录,这会更加健壮。
select mt.MachineId, mt.TripTime, min(ms.StartTime) as StartTime,
datediff(hour, mt.TripTime, min(ms.StartTime)) as HoursDifference
from MachineTrip mt join
MachineStart ms
on mt.MachineId = ms.MachineId and
mt.TripTime < ms.StartTime
group by mt.MachineId, mt.TripTime;
注意我使用了与Ali相同的命名约定,因此您可以在SQL Fiddle上尝试它。