SQL получает только элементы со всеми значениями в столбце

#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 — лучший способ решить вашу проблему, потому что он также удаляет ваше пустое пространство…

Спасибо!!!