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;