Выберите запись, только если она содержит одинаковое значение столбца для всех строк - PullRequest
1 голос
/ 28 апреля 2020

У меня есть таблица, как показано ниже.

Sample data.

Я хочу job_id, только если она отклонена всеми.

Я попытался использовать group by для подсчета результата, если он не отклонен всеми.

Итак, я проверю, является ли хотя бы одна запись таковой, которая все еще не отклонена.

Но это даст мне jobs not rejected by all.

Я хочу job_id из тех заданий, которые rejected by all.

В приведенном выше примере должна быть дана запись с job_id =2

  const jobRejectedByAll = await MatchedTechnician.findAll({
    where: {
      is_rejected: false,
      job_id: allMatchedJobs,
    },
    group: ['job_id'],
    having: sequelize.literal(`count(job_id) > 1`),
  });

Запрос:

SELECT job_id
     , 
  FROM matched_technicians AS MatchedTechnician
 WHERE MatchedTechnician.is_rejected = FALSE 
   AND MatchedTechnician.job_id IN (2, 3)
 GROUP 
    BY job_id
 HAVING COUNT(job_id) > 1;

1 Ответ

1 голос
/ 28 апреля 2020

Вы можете использовать запрос NOT EXISTS, чтобы проверить, что значение is_rejected не равно false:

SELECT DISTINCT job_id
FROM matched_technicians m1
WHERE NOT EXISTS (SELECT * 
                  FROM matched_technicians m2 
                  WHERE m2.job_id = m1.job_id 
                    AND (m2.is_rejected = false
                      OR m2.is_rejected IS NULL)
                  )

Вывод:

job_id
2

Демонстрация включена dbfiddle

Альтернативный способ запроса - подсчитать количество строк для данного job_id и сравнить его с количеством значений true; если они совпадают, задание было отклонено:

SELECT job_id
FROM matched_technicians
GROUP BY job_id
HAVING COUNT(*) = SUM(is_rejected)

Демонстрация на dbfiddle

Обновление

Sequelize версия для второго подхода:

 const jobsRejectedByAllTechs = await MatchedTechnician.findAll({
    group: ['job_id'],
    having: Sequelize.literal('count(*) = SUM(is_rejected)'),
    attributes: ['job_id'],
  });
...