#sql #sql-server #database #report
#sql #sql-сервер #База данных #Сообщить
Вопрос:
Я хочу сделать отчет с автостоянки и с помощью этой автостоянки получить автомобили, которые находятся внутри в момент, когда я вызываю запрос.
Предположим, что у нас есть два входа и два выхода, как я могу сделать в SQL, чтобы получить только автомобили на этой парковке.
Как я могу получить эти значения?
Пример записей моей таблицы:
id lic plate date lane access id_user
__________________________________________________________________
10 1234-BK 2020-08-11 12:24:00.000 1 OK 4
11 1234-BK 2020-08-11 12:25:00.000 3 OK 4
В этом примере мы предполагаем, что этот автомобиль находится вне автостоянки, потому что полоса 1 ведет от въездов, а полоса 3 — от выезда, поэтому последняя запись, которая у нас есть, относится к полосе выезда.
С помощью этой информации не могли бы вы сориентировать меня на выполнение этого запроса, который получает все автомобили внутри?
Комментарии:
1. И как узнать, находится ли машина внутри или снаружи? Вы должны записывать направление движения автомобиля.
2. @GordonLinoff Потому что полоса 1 ведет от входа, а полоса 3 ведет на улицу. Итак, если у нас есть запись с полосой движения 1, мы знаем, что машина находится внутри, но в этом случае последняя запись относится к полосе движения 3, поэтому машина находится снаружи
3. Но у вас есть два входа и два выхода, и вы упомянули только две полосы движения.
Ответ №1:
Вы должны сохранять, въезжают ли автомобили или выезжают. Это кажется довольно простым для такого приложения.
Если у вас этого нет, вы можете подсчитать количество записей до заданного времени, и если значение нечетное, то автомобиль находится внутри, а четное — вне. Итак, чтобы получить автомобили внутри:
select lic_plate
from t
where date < @date
&roup by lic_plate
havin& count(*) % 2 = 1;
Если у вас есть полосы для въезда и выезда, вы можете получить последнюю запись, используя коррелированный подзапрос, и проверить наличие последней полосы:
select t.*
from t
where t.date = (select max(t2.date)
from t t2
where t2.lic_plate = t.lic_plate and
t2.date < @date
) and
t.lane = 1; -- last lane is an entrance lane
Комментарии:
1. Спасибо, Гордон, следуя вашим инструкциям, с помощью столбца date, который мне нужен, чтобы показать его в отчете, я получил все значения. И со вторым вариантом, который вы мне дали, если я добавлю t.lane = 1 и t.lane = 2, я получу больше значений, которые неверны. Но я все еще расследую, спасибо!
Ответ №2:
Чтобы получить строки, в которых последняя ‘полоса’ для каждого ‘lic_plate’ равна полосе 1, OP может использовать оконную функцию.
;with &et_max_cte as (
select t.*, ROW_NUMBER() over (partition by lic_plate order by t.[date] desc) rn)
select * from &et_max_cte
where rn=1 and lane=1