Sql - 基于几个连接计数/有查询的困难

时间:2010-09-18 10:05:41

标签: sql count inner-join having-clause

我很难让我的查询正常工作。基本上,它应该做的只是返回尚未填补的空缺。例如,空缺可以具有预先确定的限制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,candidate,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. 然后客户决定撤销(撤销状态)
  4. 这将产生如下条目: -

    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 :(得分:0)

问题是你忽略了这样一个事实,即预订状态可能有多个entires用于相同的预订ID,因此您需要先过滤有效的预订单,如下所示

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

此查询将仅返回待处理或处于活动状态的预订ID,然后您可以根据此进一步应用您在所提及的查询中应用的所有联接来过滤空缺。 我已经粗略地修改了你的查询来做这件事,检查它是否有效

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

答案 1 :(得分:0)

您正在计算状态为1或2的预订,但我认为您应该计算不具有3或4状态的预订 - 即消除已拒绝或已撤销的预订。

实际上,我现在看到您只使用预订表中的联接选择一个预订状态。我怀疑那时的数据。您确定 booking_status_id 中的ID引用的预订状态是最新的吗?

对此进行了探讨,我会检查以下内容:

  1. 是否有多个具有相同ID的预订状态?
  2. 链接的预订状态是最新的吗?
  3. 您确定要加入状态 ID,而不是预订 ID?
  4. 除此之外,我看不到它。