使用SELF JOIN进行简单的MySQL查询

时间:2017-07-20 12:21:55

标签: mysql sql

我有一张名为 image 的表格,这是一张相机拍摄的图像表格,用于记录变量 reg 下的车辆登记,拍摄的照相机编号是变量摄像机和变量 whn 下yyyy-mm-dd 00:00:00形式的时间戳。我被要求找到以下内容:

“对于由摄像机19捕获的每辆车 - 显示登记,摄像机19的最早时间以及离开该区域的时间和摄像机。”

因此,我发现摄像机19捕获任何特定汽车的最短时间,然后是该日期的最新时间,每辆汽车都被拍摄下来的相机一起拍摄。到目前为止,我有以下代码:

SELECT early.reg,
   LEFT(MIN(early.whn), 10) AS date,
   RIGHT(MIN(early.whn), 8) AS 'in',
   RIGHT(MAX(late.whn), 8) AS 'out'
FROM image late
JOIN image early ON (early.reg = late.reg)
WHERE (early.camera = 19)
GROUP BY early.reg

这完全正常,我只需要添加相机,最大时间被捕获的最大时间由 RIGHT(MAX(late.whn),8)AS'out'我正在努力做到这一点。我尝试在SELECT调用中添加 late.camera ,但显然你必须添加 GROUP BY late.camera ,它返回在每个摄像头捕获的最新时间。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:0)

你几乎需要额外的groupby,只需添加一个where子句来限制late.whn只返回最大值

SELECT early.reg,
       LEFT(MIN(early.whn), 10) AS date,
       RIGHT(MIN(early.whn), 8) AS 'in',
       RIGHT(MAX(late.whn), 8) AS 'out',
    late.camera
    FROM image late
    JOIN image early ON (early.reg = late.reg)
    WHERE (early.camera = 19)
    and (late.whn = (select max(whn) from late))
    GROUP BY early.reg, late.camera

答案 1 :(得分:0)

好的,现在更好地理解并澄清解释,以确保我得到你想要的......我得到的印象如下:

您正在监控交通,例如收费公路。沿着南北或东/西的路线有不同的摄像机。在任何给定日期,您都有一个列表,列出了路线上所有摄像机读取的所有记录交易。你想知道,对于任何通过特定摄像机的汽车(我们都不知道它的方向性基础),你想知道汽车最终在这条航线上的摄像机范围。例如:相机1-30。你知道汽车在相机19的视线范围内,但他们可能会在相机22,26,29之后离开公路,无论如何。所以,对于在19号相机上看到的那些车,他们经过的最后一台相机就在那里。

如果这是正确的,我接近意图。内部查询几乎相同。对于给定的车辆登记ID,我仍然存储它被发现的最小和最大日期(例如,可能已经在摄像机4的路上,并且在摄像机27处关闭,假设摄像机是顺序的,但不是必需的)。基于此的HAVING子句要求相机19是包含在行程中的一个相机。如果有人在相机1上相机并在相机18处关闭,则不会包括它们(假设相机是真正连续的,但更多的是用于跟随目的)。

所以现在我有所有注册,最小和最大日期/时间。现在,我根据注册和相应的最小或最大日期重新加入相同的图像表,因为每次注册只需要一个记录,不需要在外层进行分组。对于给定的摄像机,您永远不会有重复的时间,并且它必须存在于PQ查询中。

现在,只需拉动相应的相机即可。因此,下面的查询实际上给出了他们首先被识别出来的相机,合格为通过相机19,以及它们最后被相机识别的位置。

SELECT
      PQ.Reg,
      LEFT(PQ.MinDateForDay, 10) AS date,
      RIGHT(PQ.MinDateForDay, 8) AS 'in',
      iMinDateCam.Camera CameraIn,
      PQ.TimeAtCamera19,
      RIGHT(PQ.MaxDateForDay, 8) AS 'out',
      iMaxDateCam.Camera CameraOut
   from
      ( SELECT 
              i.reg,
              min( i.whn ) as MinDateForDay,
              MAX( case when i.Camera = 19 then i.whn else '' end ) TimeAtCamera19,
              max( i.whn ) as MaxDateForDay
           FROM 
              image i
           GROUP BY 
              i.reg 
           having
              MAX( case when i.Camera = 19 then 1 else 0 end ) = 1 ) PQ
      join image iMinDateCam
         ON PQ.reg = iMinDateCam.reg
         AND PQ.MinDateForDay = iMinDateCam.whn
      join image iMaxDateCam
         ON PQ.reg = iMaxDateCam.reg
         AND PQ.MaxDateForDay = iMaxDateCam.whn