Php 组合2个MySQL查询

Php 组合2个MySQL查询,php,mysql,sql,Php,Mysql,Sql,我有两个问题: 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,

我有两个问题:

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
这给了我4行的结果

这些行/产品之间的一个共同点是,4个具有
filter\u id
130的行/产品中有3个也具有
filter\u id
126,我想修改查询,只给出具有所示
filter\u id
的两个(或更多,取决于应用的
filter\u id
的产品)的结果

我试过了

... 
AND FIND_IN_SET(fap.filter_id,'126', '130') 
ORDER BY p.products_date_added DESC, pd.products_name
但是我得到了53行/产品的结果,这意味着它显示了所有具有任一过滤器的产品,而我在本例中查找的结果仅是同时具有
filter\u id
的3行


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

在filter\u association\u products和filter in
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
选择sql\u缓存不同的p.products\u映像,
p、 产品(附图1),
产品名称,
p、 产品数量,
p、 产品型号:,
p、 订购的产品,
p、 产品编号:,
p、 产品价格,
p、 添加产品(日期),,
p、 产品重量,
p、 产品长度:,
p、 产品宽度:,
p、 产品高度:,
p、 产品(税务)类别(识别号),,
p、 产品和用户状态,
如果(s.status,s.specials\u new\u products\u price,NULL)作为specials\u new\u products\u price,
如果(s.status、s.specials\u new\u products\u price、p.products\u price)作为最终价格
来自产品p
左联特价
p.products\u id=s.products\u id上
左连接产品到类别p2c
在p.products\u id=p2c.products\u id上
左连接产品描述
在p.products\u id=pd.products\u id上
左加入过滤器协会产品fap1
在p.products\u id=fap1.products\u id上
左加入过滤器协会产品fap2
在p.products\u id=fap2.products\u id上
左连接产品属性
在p.products\u id=pa.products\u id上
其中p.products\u status='1'

和date_sub(curdate(),间隔3000天)使用
groupby
获取所需的产品信息。您也可以加入其他信息,但这是基本查询:

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
选择p*
从产品p连接
特色菜
p.products\u id=s.products\u id加入
产品类别p2c
在p.products\u id=p2c.products\u id连接上
产品描述
在p.products\u id=pd.products\u id连接上
过滤器协会产品fap
在p.products\u id=fap.products\u id上加入
产品属性
在p.products\u id=pa.products\u id上
其中p.products_status='1'和

date_sub(curdate(),间隔3000天)虽然Mikey和Gordon Linoff的回答都不错,但我更喜欢Gordon的方法,因为它的可扩展性。然而,他的答案有一些语法错误,切换到联接没有产生任何结果,所以我不得不按照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;
选择sql\u缓存不同的p.products\u映像,
p、 产品(附图1),
产品名称,
p、 产品数量,
p、 产品型号:,
p、 订购的产品,
p、 产品编号:,
p、 产品价格,
p、 添加产品(日期),,
p、 产品重量,
p、 产品长度:,
p、 产品宽度:,
p、 产品高度:,
p、 产品(税务)类别(识别号),,
p、 产品和用户状态,
如果(s.status,s.specials\u new\u products\u price,NULL)作为specials\u new\u products\u price,
如果(s.status、s.specials\u new\u products\u price、p.products\u price)作为最终价格
来自产品p
左联特价
p.products\u id=s.products\u id上
左连接产品到类别p2c
在p.products\u id=p2c.products\u id上
左连接产品描述
在p.products\u id=pd.products\u id上
内部连接过滤器协会产品fap
在p.products\u id=fap.products\u id上
左连接产品属性
在p.products\u id=pa.products\u id上
其中p.products\u status='1'

和日期(curdate(),间隔3000天)<代码>左连接
中有一个条件,其中
相当于
内部连接
。考虑到所需的额外连接的数量,从长远来看,这也是不可扩展的。这是事实,但它是最简单的普通SQL,适用于给定的请求。还有内接vs左加哪里是味觉的东西。不,不是;对于未来的维护人员来说,这是一个错误和危险。它还可能(对哑RBM)施加性能惩罚。你的代码要清楚。你真的想要那个关系吗?如果它不存在,就把它排除在外?然后使用
内部连接(最好将所有相关关系粘贴在
ON
子句中)。如果数据存在,是否需要该关系;如果不存在,是否只需要“主”数据?使用
左连接
。如果这在代码审查中出现,我会要求更改。谢谢您的编辑,Mikey,现在也可以了。阅读这些评论,我有点担心这种方法对性能的影响,因为我们有很多过滤器可以应用于查询,而不是像示例中那样只有2个@发条缪斯-戈登的答案是什么意思?我修正了第二个问题。至于评论:在这种情况下,左连接和内部连接的结果没有区别,发条缪斯只是说内部连接更清晰。另一点是:如果您使用其中一个查询,您必须在第一个语句中添加一个join和一个where子句,并在第二个语句中为每个进一步的筛选器id添加带有subselect的where子句,因此这不是很好的可扩展性。可能是重复的,Gordon。按原样执行此查询将生成sql
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
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;