Найти записи ближайшей даты SQL - PullRequest
0 голосов
/ 13 марта 2019

У меня есть таблица dbo.X с DateTime столбцом lastUpdated и столбец кода продукта CodeProd, который может содержать сотни записей, с дублированием CodeProd, поскольку таблица используется в качестве "истории запасов"

Моя хранимая процедура имеет параметр @Date, я хочу получить все CodeProd, ближайшие к этой дате, например, если у меня есть:

+----------+--------------+--------+
| CODEPROD | lastUpdated  | STATUS |
+----------+--------------+--------+
|       10 |   2-1-2019   |   C1   |
|       10 |   1-1-2019   |   C2   |
|       10 |   31-12-2019 |   C1   |
|       11 |   31-12-2018 |   C1   |
|       11 |   30-12-2018 |   C1   |
|       12 |   30-8-2018  |   C3   |
+----------+--------------+--------+

и @Date = '1-1-2019'

Я хочу получить:

+----+--------------+------+
| 10 |    1-1-2019  |   C2 |
| 11 |   31-12-2018 |   C1 |
| 12 |   30-8-2018  |   C3 |
+----+--------------+------+

Как это найти?

Ответы [ 4 ]

2 голосов
/ 13 марта 2019

Вы можете использовать TOP(1) WITH TIES, чтобы получить одну строку с ближайшей датой для каждого CODEPROD, который должен быть меньше указанной даты.

Попробуйте следующий код.

SELECT TOP(1) WITH TIES * 
FROM   [YourTableName] 
WHERE  lastupdated <= @date 
ORDER  BY Row_number() 
            OVER ( 
              partition BY [CODEPROD] 
              ORDER BY lastupdated DESC); 
0 голосов
/ 13 марта 2019

С group by codeprod вы можете получить минимум abs(datediff(d, @date, lastupdated)).Затем присоединитесь к таблице:

declare @date date = '2019-01-01';
select t.* 
from tablename t inner join (
  select codeprod, min(abs(datediff(d, @date, lastupdated))) mindif 
  from tablename 
  group by codeprod
) g on g.codeprod = t.codeprod and g.mindif = abs(datediff(d, @date, t.lastupdated))

См. Демоверсию

0 голосов
/ 13 марта 2019

Вы можете использовать оконные функции:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY codeprod ORDER BY lastupdated DESC) AS rn
    FROM t
    WHERE lastupdated <= @date
)
SELECT *
FROM cte
WHERE rn = 1
0 голосов
/ 13 марта 2019

Вы можете использовать apply:

select distinct t.CODEPROD, t1.lastUpdated, t1.STATUS
from table t cross apply
     ( select top (1) t1.*
       from table t1 
       where t1.CODEPROD = t.CODEPROD and t1.lastUpdated <= @date
       order by t1.lastUpdated desc
     ) t1;
...