задача SQL server
SELECT * FROM Visits v
INNER JOIN (
SELECT PointID, MAX(VisitDate) as Maate FROM Visits
WHERE EmployeeName=@employee AND Month=@month
GROUP BY PointID
) v2 ON v.VisitDate = v2.Maate
SELECT *
FROM (SELECT row_number over (partition by PointID order by VisitDate desc) rn
, V.*
FROM Visits V
WHERE EmployeeName=@employee AND Month=@month
)
WHERE rn = 1
имеет ли смысл сделать табличную функцию для выборки максимальных дат?
если делать, то обязательо inline! (есть два типа - inline и multi-statement а так - как хочешь
так что правильно ли я понял - inline функция - которая определяется единственным селектом, без внутренних табличных переменных который возвращаются в явном виде?
да
FROM (SELECT rank over (partition by PointID order by VisitDate desc) rn
, V.*
FROM Visits V
WHERE EmployeeName=@employee AND Month=@month
)
WHERE rn = 1
Может быть время не указано.
Стандартная задача на top N with ties:
select top 1 with ties
id_employee,
id_point,
month,
visit_date,
additional_info
from table_of_visit a
where a.id_employee = <сотрудник>
month = <месяц>
order by
ROW_NUMBER over (partition by id_point order by visit_date desc)
Я думаю, top with ties будет менее эффективен фильтрации по row_number из-за сортировки
вообще, больше 3 лет на ms sql уже не писал, могу ошибаться насчёт эффективности, конечно
Сотрудник может посетить 2 (или больше) точки за день и если нет времени посещения, то непонятно какую точку брать. row_number уберет все кроме одной, rank оставит все (но если время будет указано, то rank все равно правильно сработает).
К сожалению, не могу скопировать детализацию/планы - сервер в другой сети, но мои слова подтверждаются - у меня фильтрация на 200К строк примерно вдвое быстрее
Сотрудник может посетить 2 (или больше) точки за день и если нет времени посещения, то непонятно какую точку брать. row_number уберет все кроме одной, rank оставит все (но если время будет указано, то rank все равно правильно сработает).В задаче подразумевается, что нужно выбрать одну точку. Например, тебе нужно будет делать из результатов запроса select into в переменную. В случае двух строк выпадет ошибка.
Хотя там в условии задачи написано, что нужно вытащить одну запись по каждой точке, так что это утверждение, как и твоё, тоже не имеет практического смысла.
Нет конечно, с with ties у тебя две операции сортировки - для row_number + order by, с фильтрацией - только одна.Странно, ведь в order by при ties не указывается, в каком порядке отображать точки, указывается только partition по ним. Выходит, что второй сортировки всё таки не происходит, так как нет информации, по чему её производить.
Но если ты говоришь, что без ties быстрее, то определённо в моём решении есть какой-то изъян.
Как работает with ties: захватывает первые top (N) и добавляет строки, имеющие тот же порядок сортировки с последней, не вошедшие в N. Но для этого все равно идет сортировка - собственно, по row_number в нашем случае
Сотрудник может посетить 2 (или больше) точки за день и если нет времени посещения, то непонятно какую точку брать. row_number уберет все кроме одной, rank оставит все (но если время будет указано, то rank все равно правильно сработает).так и есть - в день визитов более одного, в разные точки (в одну и ту же точку двух визитов в день быть не может)
в "дополнительной информации" - содержатся прочие переменные, по которым потом рассчёт будет идти
вот её-то и надо вытащить по всем посещённым торговым точкам, самую актуальную на данный момент
Как работает with ties: захватывает первые top (N) и добавляет строки, имеющие тот же порядок сортировки с последней, не вошедшие в N. Но для этого все равно идет сортировка - собственно, по row_number в нашем случаеТак ведь это одна сортировка, по row_number единожды, а партиции между собой не сортируются.
для row_number все равно Sort в плане есть
Оставить комментарий
Elen13
есть таблица - посещение сотрудниками точексодежрится ИД сотрудника, ИД точки, месяц, дата визита, дополнительная информация
в течении периода (за месяц) сотрудник одну точку может посетить несколько раз
необходимо выбрать из этой таблицы по данному сотруднику, за указанный месяц все строки, в которых отображена информация по самому последнему за период визиту по всем посещённым точкам
как это сделать?