结合2个MySQL查询

时间:2015-12-27 12:18:35

标签: php mysql sql

我有2个查询:

SELECT     sql_cache distinct p.products_image, 
           p.products_subimage1, 
           pd.products_name, 
           p.products_quantity, 
           p.products_model, 
           p.products_ordered, 
           p.products_id, 
           p.products_price, 
           p.products_date_added, 
           p.products_weight, 
           p.products_length, 
           p.products_width, 
           p.products_height, 
           p.products_tax_class_id, 
           p.products_status, 
           IF(s.status, s.specials_new_products_price, NULL)             AS specials_new_products_price,
           IF(s.status, s.specials_new_products_price, p.products_price) AS final_price 
FROM       products p 
LEFT JOIN  specials s 
ON         p.products_id = s.products_id 
LEFT JOIN  products_to_categories p2c 
ON         p.products_id=p2c.products_id 
LEFT JOIN  products_description pd 
ON         p.products_id=pd.products_id 
INNER JOIN filter_association_products fap 
ON         p.products_id =fap.products_id 
LEFT JOIN  products_attributes pa 
ON         p.products_id = pa.products_id 
WHERE      p.products_status = '1' 
AND        date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added 
AND        fap.filter_id = 126 
ORDER BY   p.products_date_added DESC, 
           pd.products_name

这给了我52行(产品)的结果。

相同的查询只有差异:

AND fap.filter_id = 130

这给了我4行的结果。

这些行/产品之间的一个常见问题是4个filter_id 130中的3个也有filter_id 126我想修改查询以仅向我提供产品的结果两者(甚至更多,取决于所应用的filter_idfilter_id

我试过了

... 
AND FIND_IN_SET(fap.filter_id,'126', '130') 
ORDER BY p.products_date_added DESC, pd.products_name

但是我获得了53行/产品的结果,这意味着它显示了所有具有过滤器的产品,而我在这种情况下寻找的结果只有3行同时具有filter_id

重写查询以获得正确结果的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

使用GROUP BY获取所需的产品信息。您也可以加入其他信息,但这是基本查询:

SELECT p.*
FROM products p JOIN
     specials s 
     ON p.products_id = s.products_id JOIN
     products_to_categories p2c 
     ON p.products_id = p2c.products_id JOIN
     products_description pd 
     ON p.products_id = pd.products_id JOIN
     filter_association_products fap 
     ON p.products_id = fap.products_id JOIN
     products_attributes pa 
     ON p.products_id = pa.products_id 
WHERE p.products_status = '1' AND
      date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added AND
      fap.filter_id IN (126, 130)
GROUP BY p.products_id
HAVING COUNT(DISTINCT fap.filter_id) = 2;  -- make sure both match

我认为LEFT JOIN没有任何理由(至少对于大多数表格而言,因为filter_association_products之前的所有内容都被WHERE转换为内部联接(),所以我把它们改成了内连接。

答案 1 :(得分:1)

在filter_association_products上制作两个LEFT JOIN并在WHERE中过滤,如下所示:

 SELECT     sql_cache distinct p.products_image, 
               p.products_subimage1, 
               pd.products_name, 
               p.products_quantity, 
               p.products_model, 
               p.products_ordered, 
               p.products_id, 
               p.products_price, 
               p.products_date_added, 
               p.products_weight, 
               p.products_length, 
               p.products_width, 
               p.products_height, 
               p.products_tax_class_id, 
               p.products_status, 
               IF(s.status, s.specials_new_products_price, NULL)             AS specials_new_products_price,
               IF(s.status, s.specials_new_products_price, p.products_price) AS final_price 
    FROM       products p 
    LEFT JOIN  specials s 
    ON         p.products_id = s.products_id 
    LEFT JOIN  products_to_categories p2c 
    ON         p.products_id=p2c.products_id 
    LEFT JOIN  products_description pd 
    ON         p.products_id=pd.products_id 
    LEFT JOIN filter_association_products fap1 
    ON         p.products_id =fap1.products_id 
    LEFT JOIN filter_association_products fap2 
    ON         p.products_id =fap2.products_id 
    LEFT JOIN  products_attributes pa 
    ON         p.products_id = pa.products_id 
    WHERE      p.products_status = '1' 
    AND        date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added 
    AND        fap1.filter_id = 126 
    AND        fap2.filter_id = 130 
    ORDER BY   p.products_date_added DESC, 
               pd.products_name

另一种方法(子选择):

 SELECT     sql_cache distinct p.products_image, 
               p.products_subimage1, 
               pd.products_name, 
               p.products_quantity, 
               p.products_model, 
               p.products_ordered, 
               p.products_id, 
               p.products_price, 
               p.products_date_added, 
               p.products_weight, 
               p.products_length, 
               p.products_width, 
               p.products_height, 
               p.products_tax_class_id, 
               p.products_status, 
               IF(s.status, s.specials_new_products_price, NULL)             AS specials_new_products_price,
               IF(s.status, s.specials_new_products_price, p.products_price) AS final_price 
    FROM       products p 
    LEFT JOIN  specials s 
    ON         p.products_id = s.products_id 
    LEFT JOIN  products_to_categories p2c 
    ON         p.products_id=p2c.products_id 
    LEFT JOIN  products_description pd 
    ON         p.products_id=pd.products_id 
    LEFT JOIN  products_attributes pa 
    ON         p.products_id = pa.products_id 
    WHERE      p.products_status = '1' 
    AND        date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added 
    AND  126 in (select fap1.filter_id from filter_association_products fap1 
                 where p.products_id = fap1.products_id)
    AND  130 in (select fap2.filter_id  from  filter_association_products fap2 
                 where p.products_id = fap2.products_id)
    ORDER BY   p.products_date_added DESC, 
               pd.products_name

答案 2 :(得分:1)

虽然Mikey和Gordon Linoff的答案都很好,但由于其可扩展性,我更倾向于Gordon的方法。但是,他的答案有一些语法错误,切换到JOINs没有产生任何结果,因此我不得不将它们修改为LEFT JOIN,如Mikey所建议的那样。 (谢谢你们俩)。 这是最终的查询:

SELECT     sql_cache distinct p.products_image, 
           p.products_subimage1, 
           pd.products_name, 
           p.products_quantity, 
           p.products_model, 
           p.products_ordered, 
           p.products_id, 
           p.products_price, 
           p.products_date_added, 
           p.products_weight, 
           p.products_length, 
           p.products_width, 
           p.products_height, 
           p.products_tax_class_id, 
           p.products_status, 
           IF(s.status, s.specials_new_products_price, NULL)             AS specials_new_products_price,
           IF(s.status, s.specials_new_products_price, p.products_price) AS final_price 
FROM       products p 
LEFT JOIN  specials s 
ON         p.products_id = s.products_id 
LEFT JOIN  products_to_categories p2c 
ON         p.products_id=p2c.products_id 
LEFT JOIN  products_description pd 
ON         p.products_id=pd.products_id 
INNER JOIN filter_association_products fap 
ON         p.products_id =fap.products_id 
LEFT JOIN  products_attributes pa 
ON         p.products_id = pa.products_id 

WHERE p.products_status = '1' 
AND    date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added 
AND      fap.filter_id IN (126, 130)
GROUP BY p.products_id
HAVING COUNT(DISTINCT fap.filter_id) = 2;