2013-08-09 2 views
0

У меня есть 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 раз просто заполнители, и я забочусь об этом в приложении, которое будет использовать этот запрос.

ответ

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; 
+0

Я думал, что должен что-то делать с «датиффом», но просто не мог понять, что. Спасибо, это работало как шарм! – danielunderwood

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 строке. Затем я использовал функцию lag() в поле DateScanned, чтобы получить значение DateScanned для предыдущей строки. Для самой верхней строки DateScanned должен быть нулевым как ее первая запись, а для второго - значением первой строки. Вы можете сравнить оба этих значения, чтобы определить, хотите ли вы, чтобы отобразить вторую строку или не более

Информация на отстающей функции: http://blog.sqlauthority.com/2011/11/15/sql-server-introduction-to-lead-and-lag-analytic-functions-introduced-in-sql-server-2012/

+0

Хммм. Похоже, что это сработает, но, к сожалению, я получаю хороший 'System.Data.SqlClient.SqlException: 'LAG' не является признанным встроенным именем функции. 'В моем коде C#. Я ищу решение для этого прямо сейчас, и, по-видимому, это справедливо для SQL Server. Есть идеи? – danielunderwood

+0

По-видимому, 'LAG' работает только для SQL Server 2012. Любые идеи для 2008 R2? – danielunderwood

+0

Я не знал об этом, Гордон Линофф дал хороший ответ;) – Akash

Смежные вопросы