我想转换此查询以将GRP启动到End Grp并将开始日期启动到结束日期。
select * from (
select z.ZoneGroupId, zs.ObjectId,z.Name,case when zs.Inside=0 then 'Left' else 'Entered' end Crossing ,zs.TimeFirst
from zs join
z on zs.Zid=z.Zid
where zs.ObjectId=5696 and z.ZoneGroupId in (1095,1096) and convert(date,zs.TimeFirst)>='2016/07/01' ) s
where (ZoneGroupId=1096 and s.Crossing='Entered') or (ZoneGroupId=1095 and s.Crossing='Left')
2表涉及查询
表Z
Zid(int) Name(varchar) ZoneGroupId (int)
59 Oil 1095
60 ENR 1096
61 NRL 1096
表Zs
zsid(int) zid(int) ObjectId(int) Timefirst(datetime) Inside(boolan)
1 60 1988 2016-07-01 00:39 1
2 59 1988 2016-07-05 15:47 0
3 61 1988 2016-07-06 22:54 1
4 59 1988 2016-07-09 13:40 0
5 60 1988 2016-07-10 07:58 1
6 59 1988 2016-07-13 10:30 0
7 59 1988 2016-09-10 10:21 0
8 59 1990 2016-07-05 15:47 0
9 61 1990 2016-07-06 22:54 1
我从上面的查询中得到的结果
ZoneGroupId ObjectId Name Crossing TimeFirst
1096 1988 ENR Entered 2016-07-01 00:39
1095 1988 Oil Left 2016-07-05 15:47
1096 1988 NRL Entered 2016-07-06 22:54
1095 1988 Oil Left 2016-07-09 13:40
1096 1988 ENR Entered 2016-07-10 07:58
1095 1988 Oil Left 2016-07-13 10:30
1095 1988 Oil Left 2016-09-10 10:21
1095 1990 Oil Left 2016-07-05 15:47
1096 1990 NRL Entered 2016-07-06 22:54
必填结果
ObjectId StartName StartDate EndName EndDate
1988 Null Null ENR 2016-07-01 00:39
1988 Oil 2016-07-05 15:47 NRL 2016-7-06 22:54
1988 Oil 2016-07-09 13:40 ENR 2016-07-10 07:58
1988 Oil 2016-07-13 10:30 Null Null
1988 Oil 2016-09-10 10:21 Null Null
1988 Oil 2016-07-05 15:47 NRL 2016-7-06 22:54
答案 0 :(得分:1)
首先是您的示例数据 - 请在将来将此问题包括在内。
declare @z table (Zid int, Name nvarchar(3), ZoneGroupId int);
insert into @z values
(59, 'Oil', 1095),
(60, 'ENR', 1096),
(61, 'NRL', 1096);
declare @zs table(zsid int, zid int, ObjectId int, Timefirst datetime, Inside bit);
insert into @zs values
( 1, 60, 1988, '2016-07-01 00:39', 1),
( 2, 59, 1988, '2016-07-05 15:47', 0 ),
( 3, 61, 1988, '2016-07-06 22:54', 1 ),
( 4, 59, 1988, '2016-07-09 13:40', 0 ),
( 5, 60, 1988, '2016-07-10 07:58', 1 ),
( 6, 59, 1988, '2016-07-13 10:30', 0 ),
( 7, 59, 1988, '2016-09-10 10:21', 0 ),
( 8, 59, 1990, '2016-07-05 15:47', 0 ),
( 9, 61, 1990, '2016-07-06 22:54', 1 );
然后,我使用common-table-expressions将数据拆分为2个表left
和entered
。添加行号以按时间顺序排列。
将表连接在一起,并使用完整的外连接(从两侧获取所有行)。在连接上指定以下条件:
为了清楚起见,我还添加了一个订单。这是查询。
with entered as (
select z.ZoneGroupId
, zs.ObjectId
, z.Name
, 'Entered' Crossing
, zs.TimeFirst
, ROW_NUMBER() over (partition by ObjectID order by zs.TimeFirst) row_no
from @zs zs
inner join @z z on zs.Zid=z.Zid
where zs.Inside <> 0 and (z.ZoneGroupId = 1096 and convert(date,zs.TimeFirst)>='2016/07/01')
), [left] as (
select z.ZoneGroupId
, zs.ObjectId
, z.Name
, 'Left' Crossing
, zs.TimeFirst
, ROW_NUMBER() over (partition by ObjectID order by zs.TimeFirst) row_no
from @zs zs
inner join @z z on zs.Zid=z.Zid
where zs.Inside = 0 and (z.ZoneGroupId = 1095 and convert(date,zs.TimeFirst)>='2016/07/01')
)
select *
from [left]
full outer join entered
on entered.row_no = (select MIN(row_no) from entered e
where e.TimeFirst > [left].TimeFirst
and e.ObjectId = [left].ObjectId)
and [left].row_no = (select max(row_no) from [left] l
where l.TimeFirst < entered.TimeFirst
and l.ObjectId = entered.ObjectId)
and [left].ObjectId = [entered].ObjectId
order by isnull([left].ObjectId,entered.ObjectId), ISNULL([left].TimeFirst,entered.TimeFirst)