我有一个SQL语句,我目前正在使用它来从数据库中返回许多行:
SELECT
as1.AssetTagID, as1.TagID, as1.CategoryID,
as1.Description, as1.HomeLocationID, as1.ParentAssetTagID
FROM Assets AS as1
INNER JOIN AssetsReads AS ar ON as1.AssetTagID = ar.AssetTagID
WHERE
(ar.ReadPointLocationID='Readpoint1' OR ar.ReadPointLocationID='Readpoint2')
AND (ar.DateScanned between 'LastScan' AND 'Now')
AND as1.TagID!='000000000000000000000000'
我想要执行一个查询,该查询将从此查询获取具有最早DateScanned
的行,并且如果在该行的某个特定时间段内存在一行,则还从数据库获取另一行(比如说5秒钟。通过以降序排序选择第一条记录,最旧的记录会相对简单,但如果第二条记录在第一条记录的某个时间段内,我怎么能得到第二条记录呢?
我知道我可以使用多个查询执行此过程,但有没有办法将此过程合并到一个查询中?
我使用的数据库是SQL Server 2008 R2。
另请注意,DateScanned
次只是占位符,我将在将使用此查询的应用程序中处理此问题。
答案 0 :(得分:1)
我不确定sql server
语法,但你可以做这样的事情
SELECT * FROM (
SELECT
TOP 2
as1.AssetTagID,
as1.TagID,
as1.CategoryID,
as1.Description,
as1.HomeLocationID,
as1.ParentAssetTagID ,
ar.DateScanned,
LAG(ar.DateScanned) OVER (order by ar.DateScanned desc) AS lagging
FROM
Assets AS as1
INNER JOIN AssetsReads AS ar
ON as1.AssetTagID = ar.AssetTagID
WHERE (ar.ReadPointLocationID='Readpoint1' OR ar.ReadPointLocationID='Readpoint2')
AND (ar.DateScanned between 'LastScan' AND 'Now')
AND as1.TagID!='000000000000000000000000'
ORDER BY
ar.DateScanned DESC
)
WHERE
lagging IS NULL or DateScanned - lagging < '5 SECONDS'
我尝试按DateScanned desc
排序结果,然后排在最前面的2行。然后我在DateScanned字段上使用lag()
函数来获取前一行的DateScanned
值。对于最上面的行,DateScanned
应为null作为其第一个记录,但对于第二个记录,它应为第一行的值。然后,您可以比较这两个值以确定是否要显示第二行
答案 1 :(得分:1)
这是一种相当普遍的方法。使用min()
作为窗口函数获取最早的扫描日期,然后使用日期算法获取您想要的任何行:
select t.* -- or whatever fields you want
from (SELECT as1.AssetTagID, as1.TagID, as1.CategoryID,
as1.Description, as1.HomeLocationID, as1.ParentAssetTagID,
min(DateScanned) over () as minDateScanned, DateScanned
FROM Assets AS as1
INNER JOIN AssetsReads AS ar ON as1.AssetTagID = ar.AssetTagID
WHERE (ar.ReadPointLocationID='Readpoint1' OR ar.ReadPointLocationID='Readpoint2')
AND (ar.DateScanned between 'LastScan' AND 'Now')
AND as1.TagID!='000000000000000000000000'
) t
where datediff(second, minDateScanned, DateScanned) <= 5;