Vofka @ 11.10.10, 8:25
,
А можно воспользоваться оконной аналитической функцией FIRST_VALUE
--Создание временной таблицы с начальными данными, предварительно проверив временную таблицу на существование
IF OBJECT_ID(N'tempdb..#InitialData', N'U') IS NOT NULL DROP TABLE dbo.#InitialData
SELECT 1 id, 'Петров' id_chel, 'ЧП "У Васи"' mesto_raboty, CONVERT(date, '2010.10.01', 121) [data]
INTO #InitialData
UNION ALL
SELECT 2 id, 'Иванов' id_chel, 'ЧП "У Пети"' mesto_raboty, CONVERT(date, '2010.10.01', 121) [data]
UNION ALL
SELECT 3 id, 'Петров' id_chel, 'ЧП "У Коли"' mesto_raboty, CONVERT(date, '2010.10.05', 121) [data]
--дата среза
DECLARE @date date = '2010.10.02'
--Требуемый запрос
SELECT DISTINCT
t.id_chel
, FIRST_VALUE(t.mesto_raboty) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_mesto_raboty
, FIRST_VALUE(t.[data]) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_data_raboty
FROM dbo.#InitialData AS t
WHERE t.[data] <= @date
--Удаление временной таблицы после использования
IF OBJECT_ID(N'tempdb..#InitialData', N'U') IS NOT NULL DROP TABLE dbo.#InitialData
Результат для даты 2010.10.02:
---------------------------------------------------------
id_chel | last_mesto_raboty | last_data_raboty
---------------------------------------------------------
Иванов | ЧП "У Пети" | 2010-10-01
Петров | ЧП "У Васи" | 2010-10-01
И тоже самое в другой форме:
-- с использованием CTE
--дата среза
DECLARE @date date = '2010.10.05'
;WITH
InitialData AS (
--таблица с начальными данными
SELECT 1 id, 'Петров' id_chel, 'ЧП "У Васи"' mesto_raboty, CONVERT(date, '2010.10.01', 121) [data] UNION ALL
SELECT 2 id, 'Иванов' id_chel, 'ЧП "У Пети"' mesto_raboty, CONVERT(date, '2010.10.01', 121) [data] UNION ALL
SELECT 3 id, 'Петров' id_chel, 'ЧП "У Коли"' mesto_raboty, CONVERT(date, '2010.10.05', 121) [data]
)
--Требуемый запрос
SELECT DISTINCT
t.id_chel
, FIRST_VALUE(t.mesto_raboty) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_mesto_raboty
, FIRST_VALUE(t.[data]) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_data_raboty
FROM dbo.#InitialData AS t
WHERE t.[data] <= @date
Результат для даты 2010.10.05:
---------------------------------------------------------
id_chel | last_mesto_raboty | last_data_raboty
---------------------------------------------------------
Иванов | ЧП "У Пети" | 2010-10-01
Петров | ЧП "У Коли" | 2010-10-05
Если, при данных исходных данных, в обоих вариантах задать дату меньше 2010-10-01, то в результате получим пустой набор данных.
Цитата(Vola @ 19.09.22, 14:50)
SELECT DISTINCT
t.id_chel
, FIRST_VALUE(t.mesto_raboty) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_mesto_raboty
, FIRST_VALUE(t.[data]) OVER (PARTITION BY t.id_chel ORDER BY t.[data] DESC) as last_data_raboty
FROM dbo.#InitialData AS t
WHERE t.[data] <= @date
И, конечно, тут опечатка (во втором листинге - с использованием CTE)
вместо
FROM dbo.#InitialData AS t
надо использовать
FROM InitialData AS t