#sql #postgresql #window-functions
#sql #postgresql #окно-функции
Вопрос:
У меня есть sql-запрос, подобный этому:
SELECT m.id,
e.id AS extraction_id,
row_number() OVER (PARTITION BY m.id ORDER BY e.start_time DESC) as
start_date_rank,
e.end_time AS e_end_time,
e.status AS e_status
FROM monitors m
LEFT JOIN extractions e
ON m.id = e.monitor_id
WHERE m.is_deleted is FALSE
Моя проблема в том, что мне нужны только эти идентификаторы, где во всех столбцах e_end_time указаны временные метки. Для этого примера это только идентификатор 2. Может кто-нибудь, пожалуйста, помогите мне, как это сделать?
Идентификатор 1 имеет временную метку, но только в первой строке. Вторая и третья строки имеют значение null в столбце e_end_time, поэтому его не следует возвращать.
Комментарии:
1. База данных PostgreSQL
2. Разве результатом не должен быть идентификатор 1 и 2, поскольку у них обоих есть временные метки?
3. Потому что мне нужны только идентификаторы, в которых все строки e_end_time имеют временную метку.
4. идентификатор 1 имеет значение метки времени, мы что-то здесь упускаем или смотрим на разные изображения 🙂
5. Могу ли я предложить вам перефразировать это конкретное предложение, поскольку не очевидно, что это то, чего вы хотите (хотя ваш комментарий совершенно ясен :))
Ответ №1:
Добавьте вложенный запрос NOT IN в ваше предложение WHERE
WHERE m.is_deleted is FALSE
AND m.id NOT IN (SELECT DISTINCT monitor_id
FROM extractions
WHERE end_time IS NULL)
Ответ №2:
Добавление этого в предложение where должно удалить идентификаторы, которые имеют нулевое конечное время
and m.id not in (select id from monitors where e_end_time is null)
SELECT m.id,
e.id AS extraction_id,
row_number() OVER (PARTITION BY m.id ORDER BY e.start_time DESC) as
start_date_rank,
e.end_time AS e_end_time,
e.status AS e_status
FROM monitors m
LEFT JOIN extractions e
ON m.id = e.monitor_id
WHERE m.is_deleted is FALSE
and m.id not in (select id from monitors where e_end_time is null)
Комментарии:
1. Вы делаете это неправильно, это будет включать в себя множество строк в результате
Ответ №3:
Вы можете просто использовать group by
:
SELECT m.id
FROM monitors m LEFT JOIN
extractions e
ON m.id = e.monitor_id
WHERE m.is_deleted is FALSE
GROUP BY m.id
HAVING COUNT(*) = COUNT(e.end_time);
Комментарии:
1. И почему это должно быть анонимно отклонено? Похоже, это делает именно то, что хочет OP, то есть получить все
id
s, в которых нетNULL
значенийe.end_time
.
Ответ №4:
SELECT m.id,
e.id AS extraction_id,
row_number() OVER (PARTITION BY m.id ORDER BY e.start_time DESC) as
start_date_rank,
e.end_time AS e_end_time,
e.status AS e_status
FROM monitors m
LEFT JOIN extractions e
ON m.id = e.monitor_id
WHERE m.is_deleted is FALSE AND DATALENGTH(e.end_time)<>0
Функция DATALENGTH() возвращает количество байтов, используемых для представления выражения.
DataLength — лучший способ решить вашу проблему, потому что он также удаляет ваше пустое пространство…
Спасибо!!!