SQL DYNAMIC PIVOT - 有条件

时间:2014-07-02 13:02:08

标签: sql pivot pivot-table

我有以下查询,它返回一个汽车注册号以及它看到的日期和看到它的相机:

SELECT PLATE_READ.RegNumber, PLATE_READ.DateSeen, PLATE_READ.CameraId FROM PLATE_READ

REG         DATESEEN               CAMERAID
===         ========               ========
5897HHS     20/12/2013 12:10:57    2
5897HHS     20/12/2013 12:05:03    1
G2412       02/07/2014 13:22:01    1
G2412       02/07/2014 13:24:05    2
G6981V      02/07/2014 14:25:08    1

我希望能够查询并在每个注册号码中返回1行,说明每个相机的日期,使用以下格式:

REG         1                    2        
===         ===================  ===================
G2412       02/07/2014 13:22:01  02/07/2014 13:24:05   
5897HHS     20/12/2013 12:05:03  20/12/2013 12:10:57 

结果应按照摄像机为1的降序日期排序。摄像机1的日期必须小于摄像机2.

请注意,相机1和相机2可能会多次看到相同的印版,但最后的条目只能用于两者。

我尝试了几个线程,但没有运气。

2 个答案:

答案 0 :(得分:2)

据我所知,标准是:

  • 两台相机必须看到Reg
  • 相机2次必须在相机1次之后。

我还假设您之前使用的是SQL Server。

我接近这个的方式可能会略微违反直觉,但我会发现相机2的最新目标是每个reg,然后在相机之前找到相机的目标:

SELECT  C2.Reg, C1.[1], C2.[2]
FROM    (   SELECT  Reg, [2] = MAX(DateSeen)
            FROM    T
            WHERE   CameraID = 2
            GROUP BY T.Reg
        ) AS C2
        CROSS APPLY
        (   SELECT  TOP 1 [1] = DateSeen
            FROM    T
            WHERE   T.Reg = C2.Reg
            AND     T.DateSeen < C2.[2]
            ORDER BY T.DateSeen DESC
        ) AS C1
ORDER BY C1.[1] DESC;

<强> Example on SQL Fiddle

虽然我有可能过于复杂,但如果相机1最后一次看到它仍会显示车辆,但显示之前相机1看到的时间,即使用此数据

REG         DATESEEN               CAMERAID
===         ========               ========
5897HHS     20/12/2013 12:15:03    1
5897HHS     20/12/2013 12:10:57    2
5897HHS     20/12/2013 12:05:03    1

结果将是:

REG         1                       2
===         ========               ========
5897HHS     20/12/2013 12:05:03     20/12/2013 12:10:57

因此忽略了相机1的最新一行,因为相机2之后没有看到它。如果您想从结果中完全删除此车辆,那么您可以使用更简单的PIVOT查询:

SELECT  pvt.Reg, pvt.[1], pvt.[2]
FROM    T
        PIVOT 
        (   MAX(DateSeen)
            FOR CameraID IN ([1], [2])
        ) AS pvt
WHERE   pvt.[2] > pvt.[1]
ORDER BY pvt.[1] DESC;

<强> Example on SQL Fiddle

答案 1 :(得分:0)

如果我做得对,你需要1和2台摄像机的最后(最长)时间:

    SELECT 
         REG,
         MAX(CASE WHEN CameraID=1 THEN DATESEEN END) as [c1],
         MAX(CASE WHEN CameraID=2 THEN DATESEEN END) as [c2]
    FROM PLATE_READ
    GROUP BY REG
    HAVING MAX(CASE WHEN CameraID=1 THEN DATESEEN END)
           <
           MAX(CASE WHEN CameraID=2 THEN DATESEEN END)
   ORDER BY [c1] DESC

SQLFiddle demo