Sql - борется с количеством / имеет запрос, основанный на нескольких соединениях - PullRequest
0 голосов
/ 18 сентября 2010

Я изо всех сил пытаюсь заставить мой запрос работать.По сути, он должен только возвращать вакансии, которые не были заполнены.Например, вакансия может иметь заранее установленный лимит 5. Чтобы заполнить ее, необходимо иметь комбинацию из 5 активных или ожидающих заказов или просто 5 активных или 5 ожидающих заказов.

ожидающее бронированиеизменяется на активный, когда клиент принимает его.

Это может помочь, предоставив базовую схему моей установки: -

**tbl.vacancies:**
vacancy_id
job_category_id
business_unit_id
start_date
publication_date
end_date
limit - how many bookings it will accept

**tbl.bookings**
booking_id
candidate_id
vacancy_id
booking_status_id
user_id
date

**btl.booking_status**
id
user_id
booking_status_type_id
date

**tbl.booking_status_type**
id (1,2,3,4)
name (pending, active, rejected, revoked)

Мой запрос работает нормально при отображении всех вакансий при созданиивнутреннее соединение между таблицами job_category, business_unit ,андидат, booking_status и booking_status_type.

Но у меня есть требование, где мне нужно показывать отфильтрованные данные, основанные на том, была ли заполнена вакансия, т.е.чем лимит вакансий или он был полностью забронирован.

В настоящее время я использую запрос:

SELECT v.*, j.job_category_name, bu.business_unit_name 
FROM vacancy v 
INNER JOIN job_category j ON j.job_category_id = v.job_category_id 
INNER JOIN business_unit bu ON bu.business_unit_id = v.business_unit_id 
INNER JOIN booking b ON b.vacancy_id = v.vacancy_id 
INNER JOIN booking_status bs ON bs.id = b.booking_status_id 
WHERE 
    v.vacancy_status <> 'revoked' AND 
    v.vacancy_reference <> 'auto-generated booking' AND 
    v.business_unit_id IN (series of primary keys) AND 
(bs.booking_status_type_id = 1 OR bs.booking_status_type_id = 2) 
GROUP BY v.vacancy_id 
HAVING v.vacancy_limit > count(b.booking_id)
ORDER BY v.vacancy_id DESC

Проблема возникает, когда я отменяю бронирование (booking_status_type_id 4).Похоже, что он испортил результаты или не забрал их.

Небольшой сценарий изменения статуса при бронировании может быть следующим: -

  1. Пользователь создает бронирование (состояние ожидания)
  2. Клиент принимает (активное состояние)
  3. Клиент затем решает отозвать (состояние отмены)

Это приведет к таким записям: -

Vacancy ID = 100;
Booking ID = 10;
Booking Status entries:-

Booking_id    Booking_status_type_id
---------------------------------------
10            1
10            2
10            4

Таким образом, теоретически это бронирование не должно отображаться в результатах, поскольку позиция была удалена и стала снова доступной.

В результате в таблице booking_status_type будет 3 записи об изменении статуса бронирования.

Я не уверен, почему мой запрос не работает или он правильно построен.В качестве основного требования, когда пользователь выбирает, было ли бронирование незаполненным, в нем должны отображаться только вакансии, сумма которых не превышает предела для бронирования.

Аналогично, при выбореФильтр по заполненным вакансиям должен показывать только вакансии, в которых был достигнут лимит.

Редактировать # 1

Хорошо. Я пытался реализовать предложенное решение, но не смог заставить его работать:

SELECT v.*, j.job_category_name, bu.business_unit_name  
FROM vacancy v  
INNER JOIN job_category j ON j.job_category_id = v.job_category_id  
INNER JOIN business_unit bu ON bu.business_unit_id = v.business_unit_id  
INNER JOIN booking b ON b.vacancy_id = v.vacancy_id  
INNER JOIN  
(SELECT booking_id AS bk_id, max(booking_status_type_id) AS bStatus
FROM booking_status
GROUP BY bk_id
HAVING bStatus < 3) as filter ON filter.bk_id = b.booking_id 
WHERE  
    v.status <> 'revoked' AND  
    v.reference <> 'auto-generated booking' AND  
    v.business_unit_id IN (1, 2) 
GROUP BY v.vacancy_id  
HAVING v.limit > count(b.booking_id) 
ORDER BY v.vacancy_id DESC

Я получаю следующую ошибку:

1064 - В вашем синтаксисе SQL есть ошибка.Проверьте, соответствует ли

версии вашего сервера MySQL правильный синтаксис для использования рядом с 'SELECT booking_id AS bk_id, max (booking_status_type_id) AS b

Версия MySQL 4.0

Ответы [ 2 ]

0 голосов
/ 18 сентября 2010

Вы подсчитываете заказы, которые имеют статус 1 или 2, но я думаю, что вы должны считать заказы, которые не имеют статус 3 или 4, то есть исключить отклоненные или отозванные заказы.

На самом деле, теперь я вижу, что вы выбираете только один статус бронирования, используя соединение из таблицы заказов.Я подозреваю, что данные тогда.Вы уверены, что статус бронирования, на который указывает идентификатор в booking_status_id , является самым последним?

Поработав с этим, я бы проверил следующее:

  1. Есть ли несколько статусов бронирования с одним и тем же идентификатором?
  2. Является ли статус связанного бронирования самым последним?
  3. Вы уверены, что присоединяетесь к статусу id?, а не бронирование идентификатор?

Кроме этого, я не вижу этого.

0 голосов
/ 18 сентября 2010

проблема в том, что вы проигнорировали тот факт, что в статусе бронирования может быть несколько записей для одного и того же идентификатора бронирования, поэтому вам необходимо сначала отфильтровать действительные идентификаторы бронирования, как указано ниже

select booking_id as bk_id, max(Booking_status_type_id) status
from booking_status
group by booking_id
having status < 3

этот запрос вернет вам только те идентификаторы бронирования, которые находятся в состоянии ожидания или являются активными, затем вы можете отфильтровать вакансии на основе этого, применяя все объединения, которые вы применили в упомянутом вами запросе. я примерно изменил ваш запрос, проверьте, работает ли он

SELECT v.*, j.job_category_name, bu.business_unit_name 
FROM vacancy v 
INNER JOIN job_category j ON j.job_category_id = v.job_category_id 
INNER JOIN business_unit bu ON bu.business_unit_id = v.business_unit_id 
INNER JOIN booking b ON b.vacancy_id = v.vacancy_id 
INNER JOIN 
(select booking_id as bk_id, max(Booking_status_type_id) status
from booking_status
group by booking_id
having status < 3) as filter ON filter.bk_id = b.booking_id
WHERE 
    v.vacancy_status <> 'revoked' AND 
    v.vacancy_reference <> 'auto-generated booking' AND 
    v.business_unit_id IN (series of primary keys)
GROUP BY v.vacancy_id 
HAVING v.vacancy_limit > count(b.booking_id)
ORDER BY v.vacancy_id DESC
...