我需要从WatchDog表中获取一些行。 简化的表脚本如下
Use Question
GO
CREATE TABLE [dbo].[Errors](
[Id] [int] NOT NULL,
[WatchDogId] [int] NOT NULL,
[ErrName] [nvarchar](max) NOT NULL,
[TimeStamp] [datetimeoffset](7) NOT NULL
)
GO
CREATE TABLE [dbo].[StopperCode](
[Id] [int] NOT NULL,
[ErrorCode] [nvarchar](max) NOT NULL
)
GO
CREATE TABLE [dbo].[Watchdog](
[Id] [int] NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[ErrFlag] [bit] NOT NULL,
)
GO
INSERT [dbo].[StopperCode] ([Id], [ErrorCode]) VALUES (1, N'Stop1')
INSERT [dbo].[StopperCode] ([Id], [ErrorCode]) VALUES (2, N'Stop2')
INSERT [dbo].[Watchdog] ([Id], [Name], [ErrFlag]) VALUES (1, N'Dog1', 0)
INSERT [dbo].[Watchdog] ([Id], [Name], [ErrFlag]) VALUES (2, N'Dog2', 1)
INSERT [dbo].[Watchdog] ([Id], [Name], [ErrFlag]) VALUES (3, N'Dog3', 1)
INSERT [dbo].[Errors] ([Id], [WatchDogId], [ErrName], [TimeStamp]) VALUES (1, 2, N'Stop1 because blabla', CAST(N'2018-08-07T12:18:02.9939600+02:00' AS DateTimeOffset))
INSERT [dbo].[Errors] ([Id], [WatchDogId], [ErrName], [TimeStamp]) VALUES (2, 2, N'ErrSmall', CAST(N'2018-08-07T12:20:21.3287921+02:00' AS DateTimeOffset))
INSERT [dbo].[Errors] ([Id], [WatchDogId], [ErrName], [TimeStamp]) VALUES (3, 2, N'Stop2 bla bla', CAST(N'2018-08-07T12:20:39.3095900+02:00' AS DateTimeOffset))
INSERT [dbo].[Errors] ([Id], [WatchDogId], [ErrName], [TimeStamp]) VALUES (4, 3, N'Stop1 bla bla', CAST(N'2018-08-07T12:20:59.2625851+02:00' AS DateTimeOffset))
INSERT [dbo].[Errors] ([Id], [WatchDogId], [ErrName], [TimeStamp]) VALUES (5, 3, N'ErrSmall', CAST(N'2018-08-07T12:21:57.6044187+02:00' AS DateTimeOffset))
GO
我需要从使用日期时间过滤的WatchDog中获取失败的任务(仅返回在过去一小时内失败的任务返回不超过2次的任务),并且最后一个错误不在StopperCode表中。停止程序代码仅包含错误消息的开头。
我想基于对此样本集执行的查询中的条件获取Errors.Id = 3。因为上一个错误在StopperCode表中,所以不应返回2。如果最近一个小时内WatchDogId = 3发生了2个以上(不是来自StopperCode的)错误,则也不应该返回该错误。 现在,我可以编写带有子选择的尴尬选择,但是我想以某种方式更有效地执行此操作。而且我也不想重复两次相同的选择。
答案 0 :(得分:1)
如果我的理解正确,那么以下查询将为您服务。
;WITH CTE AS(
SELECT ROW_NUMBER() OVER(PARTITION BY WatchDogId ORDER BY ID DESC) AS RNO
,*
FROM [#Errors] E
)
SELECT C.ErrName, C.WatchDogId, W.Name
FROM CTE C
INNER JOIN [#Watchdog] W ON C.WatchDogId = W.Id
LEFT JOIN [#StopperCode] S ON C.ErrName LIKE S.ErrorCode+'%'
WHERE C.RNO=1
AND S.Id IS NULL
由于我没有得到您最后1小时的病情,我把它留给了您。
结果:
ErrName WatchDogId Name
ErrSmall 3 Dog3