我有两张表,其中包含来自多台不同计算机的警报信息。我想返回特定计算机的特定警报列表,还包括该计算机的先前警报。
表1:计算机信息
ComputerInfoId| ComputerName| [Desc]
1 | Desktop1 | Front Desk
2 | Laptop1 | Work Station 1
表2:AlarmData
AlarmDataId|ComputerInfoId|AlarmId|AlarmDate
1 2 1 03Mar2014 01:12:29
2 2 3 03Mar2014 01:12:30
3 1 7 03Mar2014 01:12:33
4 1 2 03Mar2014 01:12:36
5 1 6 03Mar2014 01:14:29
6 2 12 03Mar2014 01:15:30
7 1 2 03Mar2014 01:16:12
8 2 1 03Mar2014 01:19:40
我想查询ComputerInfoID 1和AlarmId 2.查询将返回这些记录以及之前发生的该站的2条记录。
预期数据:
ComputerInfoId|ComputerName|AlarmDataId|AlarmId| AlarmDate
1 | Desktop1 | 3 | 7 |03Mar2014 01:12:33 --Prev Record
1 | Desktop1 | 4 | 2 |03Mar2014 01:12:36 --Record fits Criteria
1 | Desktop1 | 5 | 6 |03Mar2014 01:14:29 --Prev Record
1 | Desktop1 | 7 | 2 |03Mar2014 01:16:12 --Record fist Criteria
输出数据中不需要每行后面的注释,为清楚起见,它们包含在此处。
我一直在使用的查询是:
SELECT *
FROM AlarmData AD LEFT OUTER JOIN
(SELECT *
FROM AlarmData AD2 INNER JOIN
(SELECT MAX(AlarmDatId)[MaxADID]
FROM AlarmData AD3
WHERE AD3.AlarmDataId < AD.AlarmDataId
AND AD3.ComputerInfoID = AD.ComputerInfoID) AMax
ON AD2.AlarmDataId = AMax.MaxADID) PrevAl
ON PrevAl.ComputerInfoID = AD.ComputerInfoID
WHERE AD.ComputerInfoID = 1 AND AD.AlarmId = 2
但是我收到的错误是AD.AlarmDataId和AD.ComputerInfoID无法绑定在&#34; AD3.AlarmDataId&lt; AD.AlarmDataId AND AD3.ComputerInfoID = AD.ComputerInfoID&#34;线。
答案 0 :(得分:1)
您的样本输出数据与输入数据不匹配,我无法判断您是否希望每个匹配错误有两个先前的错误,或者样本数据中每个错误的前一个错误。我认为此查询将适用于较大的数据集,其中机器的上一个警报可能不是之前的AlarmDataID。
我已在评论中指出了哪里可以更改您选择的周围行数。
with Errors as (
select *, ROW_NUMBER() over( order by alarmdate) as OrdCnt
from alarmdata AD
WHERE AD.ComputerInfoID = 1
)
select c.ComputerName, f.*
from ComputerInfo c
left outer join errors e
on c.computerInfoId = e.ComputerInfoID
left outer join errors f
on f.OrdCnt between (e.OrdCnt - 1 )and (e.OrdCnt + 0) -- Number of rows before and after
where (e.AlarmID = 2)
答案 1 :(得分:1)
我认为这对你有用:
Select ComputerInfo.ComputerInfoId ,ComputerInfo.ComputerName
,AlarmData.AlarmDataId ,AlarmData.AlarmId ,AlarmData.AlarmDate
,TB.AlarmId As PreAlarmId ,TB.AlarmDate As PreAlarmDate
From ComputerInfo
inner join AlarmData On AlarmData.ComputerInfoId =ComputerInfo.ComputerInfoId
Left Outer join AlarmData TB
On TB.ComputerInfoId = ComputerInfo.ComputerInfoId
And TB.AlarmDataId < AlarmData.AlarmDataId
And TB.AlarmDataId in ( Select Max(a_1.AlarmDataId) From AlarmData As a_1
Where a_1.ComputerInfoId = ComputerInfo.ComputerInfoId
And a_1.AlarmDataId < AlarmData.AlarmDataId)
where ComputerInfo.ComputerInfoId = 1
And AlarmData.AlarmId = 2
这是sql小提琴链接:Sql Fiddle Link
答案 2 :(得分:0)
您的结果不清楚(AlarmDataId = 5适用于ComputerInfoId = 2 NOT 1)
但是我写了一些希望就是你需要的东西
SELECT a.ComputerInfoID,
(SELECT ComputerName
FROM ComputerInfo c
WHERE c.ComputeInfoID = a.ComputerInfoID),
a.AlarmDataId, a.AlarmId, a.AlarmDate
FROM AlarmData a
WHERE a.ComputerInfoID = 1
AND ( a.AlarmId = 2
OR EXISTS ( SELECT 'a'
FROM AlarmData a2
WHERE a.ComputerInfoID = a2.ComputerInfoID
AND a2.AlarmId = 2
AND a2.AlarmDate > a.AlarmDate
AND NOT EXISTS ( SELECT 'b'
FROM AlarmData a3
WHERE a.ComputerInfoID = a3.ComputerInfoID
AND a3.AlarmDate < a2.AlarmDate
AND a3.AlarmDate > a.AlarmDate
)
)
)
答案 3 :(得分:0)
我也试过了。我为它创建了一个SQLFiddle。
要注意的事情。您可以设置它返回的深度以显示错误,因此您可以通过简单地将深度增加到2来显示最后两个错误,而不是仅显示最后两个错误:
cte.Depth + 1 <= 1 -- Depth you want to go to
在这里
alarms.Depth <= 1 -- Should equal the depth in the CTE query
运行此查询时,它会提供以下结果集:
ComputerInfoId ComputerName AlarmDataId AlarmId AlarmDate
1 Desktop1 3 7 2014-03-03 01:12:33.000
1 Desktop1 4 2 2014-03-03 01:12:36.000
1 Desktop1 6 12 2014-03-03 01:15:30.000
1 Desktop1 7 2 2014-03-03 01:16:12.000
答案 4 :(得分:0)
WITH cte
AS (
SELECT AD.ComputerInfoId
,ComputerName
,AlarmDataId
,AlarmId
,AlarmDate
FROM AlarmData AD
INNER JOIN ComputerInfo C ON AD.ComputerInfoId = C.ComputerInfoId
WHERE AD.ComputerInfoId = 1
AND AlarmId <> 2
)
SELECT ComputerInfoId
,ComputerName
,AlarmDataId
,AlarmId
,AlarmDate
FROM cte
WHERE AlarmDataId < (
SELECT Max(AlarmDataId)
FROM AlarmData
WHERE ComputerInfoId = 1
AND AlarmId = 2
)
UNION ALL
SELECT AD.ComputerInfoId
,ComputerName
,AlarmDataId
,AlarmId
,AlarmDate
FROM AlarmData AD
INNER JOIN ComputerInfo C ON AD.ComputerInfoId = C.ComputerInfoId
WHERE AD.ComputerInfoId = 1
AND AlarmId = 2
ORDER BY AlarmDataId