我目前正在从事一个项目,该项目需要我使用sql比较两个表中的数据。基本上,它的作用是检查未经预订的未授权房间使用情况。一个例子是,如果某个房间是从上午9点到上午11点预订的,那么之后的任何事情都将被视为未经授权。传感器数据将显示房间中是否有人的数据。 0代表空白,而1代表1。
这是我的SQL查询:
select
cd.ROOMID,
cd.DAY,
cd.CLASSSTARTDATE1,
cd.CLASSENDDATE1,
count(sensorD.Timestamp) as Unauthorised_Visit
from
classroomData cd
inner join
sensorData sensorD on cast(sensorD.Timestamp as date) = cast(cd.CLASSENDDATE1 as date)
where
sensorD.[Occupied Status ] = '1'
and cast(sensorD.Timestamp as time) not between cast(cd.CLASSSTARTDATE1 as time) and cast(cd.CLASSENDDATE1 as time)
group by
cd.ROOMID, cd.DAY, cd.CLASSENDDATE1, cd.CLASSSTARTDATE1
我现在面临的问题是一日,可以在一天中的任何时间预订房间。例如,A室在上午9点至晚上11点和上午11点至下午1点预订。不在9-11和11-1之间的任何时间都被视为未经授权。
结果数据
上述代码的问题是它将对不在上午9点至上午11点之间的任何数据进行计数,并且在以下情况下将与上午11点至下午1点一起计数 我已指定不计算已预订的任何数据。关于如何解决此问题的任何建议?
这是到sql小提琴中的示例sql数据库的链接:http://sqlfiddle.com/#!9/e3ea65/2
答案 0 :(得分:3)
您是否只是想在房间授权的时间段之间加入传感器数据并希望看到差异?简单的左联接将解决问题。我使通用表表达式cte1代表预订的时间段,并用一个条目填充它。第二CTE是具有两个条目的传感器数据。
实际查询是将传感器数据与预订的数据通过左联接联接在一起,空值表示没有预订时发生了传感器数据。
;with cte1 as (
select '2018-01-01 10:00' as s, '2018-01-01 12:00' as e
),
cte2 as (
select '2018-01-01 11:00' as occup
union all
select '2018-01-01 13:00' as occup
)
select
case when cte1.s is null then 'Unauthorized' else 'Authorized' end as authorized,
*
from cte2
left outer join cte1 on cte2.occup between cte1.s and cte1.e
结果:
用小提琴匹配相同的查询:
select
case when cd.ROOMID is null then 'Unauthorized' else 'Authorized'end as Authorized,
cd.ROOMID,
cd.[DAY],
cd.CLASSSTARTDATE1,
cd.CLASSENDDATE1,
COUNT(sd.Timestamp) as Unauthorised_Visit,
cast(sd.[Timestamp] as date) as dt
from
sensorData sd
left join classroomData cd on sd.[Timestamp] between cd.CLASSSTARTDATE1 and cd.CLASSENDDATE1
where
sd.[Occupied Status] = 1
group by
cd.ROOMID, cd.[DAY], cd.CLASSENDDATE1, cd.CLASSSTARTDATE1, cast(sd.Timestamp as date)