我有两个表:表1是在特定时间,日期,名称
访问建筑物Accesses
| Date | Time | Name | accesses|
-----------------------------------------------
| 2018-10-10 | 10:10:34.00 | JA | 1 |
| 2018-10-10 | 10:14:10.10 | AA | 1 |
| 2018-10-10 | 12:15:00.45 | BE | 1 |
| 2018-10-10 | 15:00:00.50 | JA | 1 |
| 2018-10-10 | 16:56:56.15 | BE | 1 |
表2显示某些访问期间是否出现故障
Failure
| Date | Time | Name | failure |
-----------------------------------------------
| 2018-10-10 | 10:10:40.00 | JA | 1 |
| 2018-10-10 | 10:15:06.00 | AA | 1 |
| 2018-10-10 | 16:57:01.14 | BE | 1 |
期望的输出
Output
| Date | Time | Name | accesses| Failure |
---------------------------------------------------------
| 2018-10-10 | 10:10:34.00 | JA | 1 | 1 |
| 2018-10-10 | 10:14:10.10 | AA | 1 | 1 |
| 2018-10-10 | 12:15:00.45 | BE | 1 | NULL |
| 2018-10-10 | 15:00:00.50 | JA | 1 | NULL |
| 2018-10-10 | 16:56:56.15 | BE | 1 | 1 |
基本上,输出将包含访问并将故障表与从访问表中检测到的最近时间相匹配。我尝试了不同的匹配时间戳的算法但我仍然得到错误,因为并非所有的访问都失败了,这就是为什么我想在输出中使用NULL。谢谢
答案 0 :(得分:1)
从评论中看来,这种连接条件似乎有效
select distinct
a.*
,Failure = case when f.Name is not null then 1 else null end
from Accesses a
left join Failure F on
f.Name = a.Name
and f.Time > dateadd(minute,-1, a.Time)
and f.Time < dateadd(minute, 1, a.Time)
and f.Date = a.Date
这是一种方式,通过从你的单独栏目中DATETIME
来制作午夜。请注意,我在每个表中添加了一行。
declare @Accesses table (Date date, Time time, Name char(2), accesses bit)
insert into @Accesses
values
('2018-10-10','10:10:34.00','JA',1 ),
('2018-10-10','10:14:10.10','AA',1),
('2018-10-10','12:15:00.45','BE',1),
('2018-10-10','15:00:00.50','JA',1),
('2018-10-10','16:56:56.15','BE',1),
('2018-10-10','23:59:56.15','XX',1)
declare @Failure table (Date date, Time time, Name char(2), failure bit)
insert into @Failure
values
('2018-10-10','10:10:40.00','JA',1),
('2018-10-10','10:15:06.00','AA',1),
('2018-10-10','16:57:01.14','BE',1),
('2018-10-11','00:00:01.15','XX',1)
select distinct
a.*
,Failure = case when f.Name is not null then 1 else null end
from @Accesses a
left join @Failure F on
f.Name = a.Name
and cast(convert(varchar,f.date) + ' ' + left(convert(varchar,f.time),8) as datetime) > dateadd(minute,-1,cast(convert(varchar,a.date) + ' ' + left(convert(varchar,a.time),8) as datetime))
and cast(convert(varchar,f.date) + ' ' + left(convert(varchar,f.time),8) as datetime) < dateadd(minute,1,cast(convert(varchar,a.date) + ' ' + left(convert(varchar,a.time),8) as datetime))
答案 1 :(得分:1)
数据库在时间表示方面有所不同。但是,一般的想法是你可以使用exists
:
select a.*,
(case when exists (select 1
from failures f
where f.name = a.name and
f.date = a.date and
f.time > a.time - interval '1' minute and
f.time < a.time + interval '1' minute
then 1 else 0
end) as failure_flag
from accesses a;
这会使用值为0
和1
的标记。显然,您可以删除else 0
子句以获取NULL
而不是0
。
如果组合日期和时间,这实际上会更准确地工作。根据数据的性质,可能不值得在午夜添加修复程序。