Как получить последнюю запись клиента по заданным параметрам в MSSQL

Рассмотрим задачу работы с таблицей clients, которая имеет следующую структуру:

  • client - уникальный идентификатор клиента
  • paramname - название параметра
  • paramvalue - значение параметра
  • date - дата записи
  • source - источник данных

В эту таблицу ежедневно загружаются данные, где для каждого клиента (client) могут изменяться параметры (paramname) и их значения (paramvalue).

Постановка задачи

Необходимо сформировать SQL-запрос для Microsoft SQL Server (MSSQL), который выберет идентификаторы клиентов (client), удовлетворяющих всем следующим условиям:

  • Параметр paramname равен 'pas'
  • Значение параметра paramvalue равно '2'
  • Источник данных source равен 'web'

При этом для каждого клиента нужно выбрать только самую последнюю запись по полю date.

Решение с использованием оконной функции

Наиболее эффективное решение использует оконную функцию ROW_NUMBER():

SELECT client, paramname, paramvalue, date, source
FROM (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY client ORDER BY date DESC) as rn
    FROM clients
    WHERE paramname = 'pas'
      AND paramvalue = '2'
      AND source = 'web'
) AS ranked
WHERE rn = 1;

Альтернативное решение с подзапросом

Более традиционный подход с использованием коррелированного подзапроса:

SELECT c1.*
FROM clients c1
WHERE c1.paramname = 'pas'
  AND c1.paramvalue = '2'
  AND c1.source = 'web'
  AND c1.date = (
    SELECT MAX(c2.date)
    FROM clients c2
    WHERE c2.client = c1.client
      AND c2.paramname = 'pas'
      AND c2.paramvalue = '2'
      AND c2.source = 'web'
  );

Ключевые моменты реализации

  • Оба запроса гарантируют выбор только последней записи для каждого клиента
  • Решение с ROW_NUMBER() обычно более производительно на больших объемах данных
  • Для ускорения выполнения запроса рекомендуется создать индекс по полям client, date, paramname, paramvalue, source