在查询中选择1条记录,其中包含重叠的开始和停止时间

时间:2015-11-20 20:38:15

标签: ms-access ms-access-2007

是否有办法编写访问查询,以便如果您有2条记录具有重叠的开始时间和结束时间,则查询仅使用持续时间最长的记录?例如,如果我有下面的数据,我每天只需要上午1点的记录和1点的记录。

示例:

Vehicle 
Number  Day of Month    Weekday Pre Midnight Hours  Login Date/Time
138         26          Monday        10.98       10/26/2015 5:48:33 AM
138         27          Tuesday       12.30       10/27/2015 5:54:51 AM
138         27          Tuesday       12.28       10/27/2015 5:55:32 AM
138         28          Wednesday     10.47       10/28/2015 5:58:31 AM
138         29          Thursday      10.97       10/29/2015 6:00:42 AM
138         30          Friday        11.50       10/30/2015 6:03:33 AM
138         31          Saturday       6.88       10/31/2015 5:51:32 AM
642         26          Monday        12.00       10/26/2015 3:19:56 AM
642         26          Monday        11.97       10/26/2015 3:20:17 AM
642         27          Tuesday       10.27       10/27/2015 3:13:19 AM
642         27          Tuesday       10.25       10/27/2015 3:13:48 AM
642         27          Tuesday        9.20       10/27/2015 2:48:59 PM
642         28          Wednesday      9.93       10/28/2015 3:41:05 AM
642         28          Wednesday      9.93       10/28/2015 3:41:37 AM
642         28          Wednesday      9.12       10/28/2015 2:53:20 PM
642         29          Thursday       9.10       10/29/2015 3:22:24 AM
642         29          Thursday       9.10       10/29/2015 3:22:58 AM
642         29          Thursday       9.02       10/29/2015 2:59:35 PM
642         30          Friday         8.17       10/30/2015 3:05:02 AM
642         30          Friday         6.20       10/30/2015 3:20:53 PM

这是我用来生成结果集的查询

SELECT [Actual Times].[Vehicle Number], 
Day([Actual Times].[Login Date/Time]) AS [Day of Month], 
Format([Actual Times].[Login Date/Time],"dddd") AS Weekday,
Sum(IIf(Day([Actual Times].[Login Date/Time])=Day([Actual Times].[Logout Date/Time]),DateDiff("n",[Actual Times].[Login Date/Time],[Actual Times].[Logout Date/Time]),IIf(Day([Actual Times].[Login Date/Time])<>Day([Actual Times].[Logout Date/Time]),(DateDiff("n",[Login Date/Time],DateValue([Logout Date/Time])))))/60) AS [Pre Midnight Hours], 
[Actual Times].[Login Date/Time]
FROM [Actual Times]
WHERE ((([Actual Times].[Login Date/Time]) Between [Start Date] And [End Date]) AND (([Actual Times].Distance)>"0.0"))
GROUP BY [Actual Times].[Vehicle Number], Day([Actual Times].[Login Date/Time]), Format([Actual Times].[Login Date/Time],"dddd"), [Actual Times].[Login Date/Time]
HAVING ((([Actual Times].[Vehicle Number]) Like '642' Or ([Actual Times].[Vehicle Number]) Like '138'));

回复后的更新编码:

SELECT Max(j.duration) AS TotalTime, j.[Vehicle Number]
FROM (SELECT
  IIF(DATEDIFF("n",at1.[Login Date/Time],at1.[Logout Date/Time]) > DATEDIFF("n",at2.[Login Date/Time],at2.[Logout Date/Time]),DATEDIFF("n",at1.[Login Date/Time],at1.[Logout Date/Time]),DATEDIFF("n",at2.[Login Date/Time],at2.[Logout Date/Time])) As Duration,
  at1.[vehicle Number],
  at1.[Login Date/Time]
 FROM
   [Actual Times] at1
   LEFT JOIN [Actual Times] at2 ON at1.[ID] = at2.[ID] AND at1.[Vehicle Number]=at2.[Vehicle Number]
 WHERE
   ((at1.[Login Date/Time] <> at2.[Login Date/Time] AND at1.[Logout Date/Time] <> at2.[Logout Date/Time])
   AND (at1.[Login Date/Time] BETWEEN at2.[Login Date/Time] AND at2.[Logout Date/Time] OR
    at2.[Login Date/Time] BETWEEN at1.[Login Date/Time] AND at1.[Login Date/Time])
   AND at2.[Login Date/Time] > at1.[Login Date/Time])
   OR at2.[Login Date/Time] IS NULL
 )  AS j
WHERE (((j.[Login Date/Time]) Between [Start Date] And [End Date]))
GROUP BY j.[Vehicle Number], j.[Login Date/Time];

1 个答案:

答案 0 :(得分:0)

我要简化文本以避免使用大量的方括号,但也许像这样的查询会这样做。道歉 - 我通常在SQL服务器通过时编写复杂的MS-Access查询,所以如果我做某事Access并不喜欢请评论。

SELECT
  Max(duration) as duration,
  vehicleNumber
FROM (
 SELECT
  IIF(DATEDIFF("n",a1.loginTime,a1,logoutTime) > DATEDIFF("n",a2.loginTime),DATEDIFF("n",a1.loginTime,a1.logoutTime),DATEDIFF("n",a2.loginTime,a2.logoutTime)) As Duration,
  a1.vehicleNumber
 FROM
   ActualTimes at1
   LEFT JOIN ActualTime at2 ON at1.VehicleNumber = at2.VehicleNumber
 WHERE
--Any better way to check two records the same one, like do they have and ID?
--In pass through SQL, I would put all these as Additional clauses on the ON
--ON part of the JOIN, but I don't think MS ACCESS SQL allows it. This makes
--it more complicated because of the left join, and still therefore including
-- non overlapping vehicle records 
   ((at1.loginTime <> at2.loginTime AND at1.logoutTime <> at2.logoutTime)
   AND (at1.loginTime BETWEEN at2.loginTime AND at2.logoutTime OR
    at2.loginTime BETWEEN at1.loginTime AND at1.logoutTime)
   AND a2.loginTime > a1.loginTime)
   OR a2.loginTime IS NULL
 ) as j
GROUP BY j.VehicleNumber