如何解决具有分组依据,联接和布尔分组的查询

时间:2019-03-06 19:01:27

标签: mysql sql

我的大学项目中有4张桌子

  1. 餐桌报价:

    id,patid,说明,preferred_language已创建

  2. 表offer_country:

    id,offer_id,patid,国家/地区

  3. 表response_clinic_reserved:

    id,offer_id,patid,clinid,国家/地区,已创建,已过期

  4. 表response_clinic_final:

    id,offer_id,patid,clinid,国家/地区,price_low,price_high,offer_description

例如,我们的ID为6的公司要求列出所有报价

我需要列出所有在美国的报价,并显示有多少最终报价和预订。但是,如果该组合我们/ 6 已预订( response_clinic_reserved )或已做出最终响应( response_clinic_final ),则不显示该报价< / p>

这是我的查询无法正常工作

SELECT offer.id, offer.description, offer.preferred_language, offer.created, count(rcr.id) as reservations, count(rcf.id) as offers 
FROM offer 
LEFT JOIN offer_country ON offer_country.offer_id = offer.id 
LEFT JOIN response_clinic_reserved rcr ON rcr.offer_id = offer.id 
LEFT JOIN response_clinic_final rcf ON rcf.offer_id = offer.id 
WHERE (offer_country.country = 'ALL' OR offer_country.country = 'us') 
  AND (rcf.country <> 'us' AND rcf.clinid <> 6) 
GROUP BY offer.id 
ORDER BY offer.created ASC 
LIMIT 50

更新时间:2019-06-03 at 10:10

我创建了一个新查询,该查询的运行方式应该正确(我认为是这样),但这可能很复杂。有没有办法使其更快?我也希望没有隐藏的错误。

SELECT offer.id, offer.description, offer.preferred_language, 
             if( 
                rcf.clinid IS NOT NULL,
                max( rcf.clinid = 6 AND rcf.country = 'us'),
                0
             ) as offer_response_present,
             if( 
                rcr.clinid IS NOT NULL,
                max( rcr.clinid = 6 AND rcr.country = 'us'),
                0
             ) as offer_reservation_present,
             offer.created, count(rcr.id) as reservations, count(rcf.id) as offers 
             FROM offer 
             LEFT JOIN offer_country 
             ON offer_country.offer_id = offer.id 
             LEFT JOIN response_clinic_reserved rcr 
             ON rcr.offer_id = offer.id 
             LEFT JOIN response_clinic_final rcf 
             ON rcf.offer_id = offer.id 
             WHERE (offer_country.country = 'ALL' OR offer_country.country = 'us') 
             GROUP BY offer.id 
             HAVING  ( offer_response_present NOT LIKE 1 AND offer_reservation_present NOT LIKE 1)
             ORDER BY offer.created ASC 
             LIMIT 50

如果在查询中的原因是在表(response_clinic_final或response_clinic_reserved)为空或没有结果的情况下,

HAVING  ( offer_response_present NOT LIKE 1 AND offer_reservation_present NOT LIKE 1)

不起作用。所以在没有结果的情况下,我会返回0

更新2019-07-03 10:40

上次查询效果不佳

count(rcr.id) as reservations, count(rcf.id) as offers 

这部分查询返回了更多的结果,而由于左联接,它应该返回更多的结果,所以我不得不像下面的查询中那样通过选择子项来修复该部分。

SELECT offer.id, offer.description, offer.preferred_language, 
             if( 
                rcf.clinid IS NOT NULL,
                max( rcf.clinid = 4 AND rcf.country = 'us'),
                0
             ) as offer_response_present,
             if( 
                rcr.clinid IS NOT NULL,
                max( rcr.clinid = 4 AND rcr.country = 'us'),
                0
             ) as offer_reservation_present,
             offer.created, 
             (SELECT Count(offer_id) FROM response_clinic_reserved WHERE offer_id = offer.id) as reservations, 
             (SELECT Count(offer_id) FROM response_clinic_final WHERE offer_id = offer.id) as offers 
             FROM offer 
             LEFT JOIN offer_country 
             ON offer_country.offer_id = offer.id 
             LEFT JOIN response_clinic_reserved rcr  ON rcr.offer_id = offer.id 
             LEFT JOIN response_clinic_final rcf 
             ON rcf.offer_id = offer.id 
             WHERE (offer_country.country = 'ALL' OR offer_country.country = 'us') 
             GROUP BY offer.id 
             HAVING  ( offer_response_present NOT LIKE 1 AND offer_reservation_present NOT LIKE 1)
             ORDER BY offer.created ASC 
             LIMIT 50

现在我想拥有更多选择,有没有一种方法可以优化此查询?

编辑2019-10-03 at 10:15

这是投入生产的最后一个版本。不知道它是否最快,但是最干净。

SELECT offer.id, offer.description, offer.preferred_language, offer.created, 
            (   
                SELECT Count(offer_id) 
                FROM response_clinic_reserved 
                WHERE offer_id = offer.id
                AND country = :clin_country
                AND clinid = :clinid
            ) as offer_response_present,

            (   
                SELECT Count(offer_id) 
                FROM response_clinic_final 
                WHERE offer_id = offer.id
                AND country = :clin_country
                AND clinid = :clinid
            ) as offer_reservation_present,

            (   
                SELECT Count(offer_id) 
                FROM response_clinic_reserved 
                WHERE offer_id = offer.id
                AND country = :clin_country
            ) as reservations, 

            (
                SELECT Count(offer_id) 
                FROM response_clinic_final 
                WHERE offer_id = offer.id
                AND country = :clin_country
            ) as offers

            FROM offer 

            LEFT JOIN offer_country 

            ON offer_country.offer_id = offer.id 

            WHERE (offer_country.country = 'ALL' OR offer_country.country = :clin_country) 

            GROUP BY offer.id 

            ORDER BY offer.created ASC 

            LIMIT 50

0 个答案:

没有答案