使用条件SQL视图合并两行

时间:2014-11-14 23:12:08

标签: sql sql-server sql-view

我有一个具有SQL脚本的视图:

    Select
        a.iAssetId,
        ac.eEventCode,
        vm.dtUTCDateTime,
        g.iGeofenceId,
        g.sGeofenceName,
        c.sCategoryName,
        c.iCategoryId,
        s.sSiteName,
        s.iSiteId,
        CASE WHEN ac.eEventCode = 6 THEN vm.dtUTCDateTime ELSE NULL END as EnterTime,
        CASE WHEN ac.eEventCode = 7 THEN vm.dtUTCDateTime ELSE NULL END as ExitTime,

CASE WHEN
 a.iAssetId  = Lead(a.iAssetId) OVER (ORDER BY a.iAssetId)
                AND g.iGeofenceId = Lead(g.iGeofenceId) OVER (ORDER BY a.iAssetId)
                AND ac.eEventCode != Lead(ac.eEventCode)  OVER (ORDER BY a.iAssetId)
                THEN DATEDIFF(minute, vm.dtUTCDateTime, Lead(vm.dtUTCDateTime)  OVER (ORDER BY a.iAssetId))  ELSE NULL END as Test


    From AssetCommunicationSummary ac
    Inner join VehicleMonitoringLog vm on vm.iVehicleMonitoringId = ac.iVehicleMonitoringId
    Inner Join Geofences g on g.iGeofenceId = vm.iGeofenceId
    Inner Join Assets a on a.iAssetId = ac.iAssetId 
    Inner Join Categories c on c.iCategoryId =  a.iCategoryId
    Inner Join Sites s on s.iSiteId = c.iSiteId
     Where ac.eEventCode = 6 OR ac.eEventCode = 7
     Group by
         a.iAssetId,
            ac.eEventCode,
            vm.dtUTCDateTime,
            g.iGeofenceId,
            g.sGeofenceName,
            c.sCategoryName,
            c.iCategoryId,
            s.sSiteName,
            s.iSiteId

我已经使用Lead来计算基于条件的前导行的时间差异(分钟)。

我现在需要根据条件合并前导行和当前行。

有可能这样做吗?

目标是在其旁边的列中使用时差在相同行中获取EnterTime和ExitTime。

我的结果是这样的:

enter image description here

5 个答案:

答案 0 :(得分:1)

您可以使用此ddl来测试并了解正在发生的事情。它是复制和粘贴准备好的,如果你想看到时间上的差异,请确保在插入每条记录之前等待。

Create table testing
(
  Id int ,
  Enter DateTime, 
  Exitt DateTime,
  Eventt int,
  GeoCode int
)

insert into testing values (1, GETDATE(),null,6,10)
insert into testing values (1, null,GETDATE(),7,10)

insert into testing values (1, GETDATE(),null,6,11)
insert into testing values (1, null,GETDATE(),7,11)

insert into testing values (2, GETDATE(),null,6,10)
insert into testing values (2, null,GETDATE(),7,10)

create table #temp1
(
  Id int, EnterTime datetime, GeoCode int
)

create table #temp2
(
  Id int, ExitTime datetime, GeoCode int
)

insert into #temp1
Select Id, MAX(Enter), GeoCode from testing where Eventt = 6 group by Id,GeoCode

insert into #temp2
Select Id, MAX(Exitt),GeoCode from testing where Eventt = 7 group by Id,GeoCode

Select t1.Id, t1.EnterTime,t2.ExitTime, t1.GeoCode, DATEDIFF(ss,t1.EnterTime,t2.ExitTime)
from #temp1 t1
inner join #temp2 t2 on t2.Id = t1.Id 
                     and t1.GeoCode = t2.GeoCode    

这基本上是伪代码,所以你需要修改,但你需要的一切就在这里。

答案 1 :(得分:1)

我猜测eventcode = 6意味着摄入时间

如果这样两个数据巴黎没有多大意义,因为退出时间是在入场时间之前,

如果事件代码6 =吸入时间,则下面的查询仅考虑amd的时间 并且退出时间应该在毕业之前。 查询基于您提供的输出而不是视图查询。

如果在视图表上执行select *为您提供输出,则将vw_table替换为 yourviewstablename

sqlfiddle的timedif中有空,因为

  • 只有一个assetid 2
  • 的实例
  • 第4和第6组的退出时间是在entertimes之前发生的

SQLFIDDLE

 select
            v1.iAssetid,
            v1.EnterTime, 
            v2.ExitTime,
            datediff(minute,  v1.Entertime, v2.Exittime) timedif


        from vw_table v1 
          left join vw_table v2 on
            v1.iAssetid= v2.iAssetid
            and v1.sCategoryNamea = v2.sCategoryNamea
            and v2.eEventcode = 7 
            and v2.dtUTCDatetime  >= v1.dtUTCDatetime  


        where  
          v1.eEventcode = 6

答案 2 :(得分:1)

如果您的事件代码总是为6和7,那么您可以使用连接本身中的该子句连接到该表两次。我想我已经在下面正确地连接了你的架构的其余部分,但如果没有,你可以调整它以适应。

Select
    a.iAssetId,
    vmEnter.dtUTCDateTime,
    g.iGeofenceId,
    g.sGeofenceName,
    c.sCategoryName,
    c.iCategoryId,
    s.sSiteName,
    s.iSiteId,
    vmEnter.dtUTCDateTime as EnterTime,
    vmExit.dtUTCDateTime as ExitTime,
    DATEDIFF(minute, vmEnter.dtUTCDateTime, vmExit.dtUTCDateTime) as ExitTime,
From Sites s
    Inner Join Categories c on s.iSiteId = c.iSiteId
    Inner Join Assets a on c.iCategoryId =  a.iCategoryId
    Inner Join AssetCommunicationSummary acEnter on a.iAssetId = acEnter.iAssetId and acEnter.eEventCode = 6
    Inner Join VehicleMonitoringLog vmEnter on vmEnter.iVehicleMonitoringId = acEnter.iVehicleMonitoringId 
    Inner Join AssetCommunicationSummary acExit on a.iAssetId = acExit.iAssetId and acExit.eEventCode = 7
    Inner Join VehicleMonitoringLog vmExit on vmExit.iVehicleMonitoringId = acExit.iVehicleMonitoringId 
    Inner Join Geofences g on g.iGeofenceId = vmEnter.iGeofenceId

答案 3 :(得分:0)

您可以通过向它们添加Row_Number来合并两个结果集,然后加入它。像

SELECT DISTINCT tbl1.col1, tbl2.col2
FROM
   (SELECT FirstName AS col1, ROW_NUMBER() OVER (ORDER BY FirstName) Number FROM dbo.UBUser) tbl1
INNER JOIN
  (SELECT LastName AS col2, ROW_NUMBER() OVER (ORDER BY LastName) Number FROM dbo.UBUser) tbl2 
ON tbl1.Number = tbl2.Number

通过这种方式,您可以在相邻行中使用EnterTime和ExitTime,并在其旁边的列中显示时差。

答案 4 :(得分:-1)

试试这个

SELECT iAssetid,
       iGeoFenceId,
       iGeoFenceName,
       sCategoryNamea,
       iCategoryid,
       sSiteName,
       Max(EnterTime) As EnterTime,
       Min(ExitTime) As ExitTime,
       Datediff(minute,  Max(EnterTime), Min(ExitTime)) As Timediff
FROM   #vw_Table
GROUP  BY iAssetid,
          iGeoFenceId,
          iGeoFenceName,
          sCategoryNamea,
          iCategoryid,
          sSiteName