MySQL 计数问题
MySQL count issue
在我的应用程序 (osCommerce) 中,我不得不修改如下所示的查询:
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 find_in_set(fap.filter_id,'126, 130')
ORDER BY p.products_date_added DESC,
pd.products_name
就这样结束,为了准确的结果:
AND fap.filter_id IN (126, 130)
GROUP BY p.products_id
HAVING COUNT(DISTINCT fap.filter_id) = 2;
我现在遇到的问题是以下查询正在使用这个新查询并给我错误的结果。
SELECT COUNT( DISTINCT p.products_id ) AS total
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
ORDER BY p.products_date_added DESC , pd.products_name
这不是给出原始查询中所有 product_id
计数的 1 行结果,而是现在给出多行结果(行数与预期的总产品数相同) 中的每个数字为 1。
主要问题似乎是 GROUP BY p.products_id
HAVING COUNT( DISTINCT fap.filter_id ) =2
有什么方法可以修改原始查询,使计数查询在仍然使用 AND fap.filter_id IN ( 126, 130 )
的同时仍能正常工作吗?
您需要使用子查询来获得您想要的结果:
select count(*)
from (<old query here>) s;
需要在product id级别进行聚合,才能得到符合原始条件的产品。计算此类产品的数量需要再次聚合。
正如 Gordon 所建议的,使用子查询通常应该可行。
由于此查询看起来像产品列表查询,并且由于您使用的是 osCommerce,因此当您修改查询以使用子查询时,您将遇到另一个核心问题:
分页结果的计数查询会失败,因为它不支持子查询。
要解决此问题,您还需要修改 catalog/includes/classes/split_page_results.php
中的核心代码
变化:
$count_query = tep_db_query("select count(" . $count_string . ") as total " . substr($this->sql_query, $pos_from, ($pos_to - $pos_from)));
收件人:
$count_query = tep_db_query("select count(*) as total from (" . $this->sql_query . ") AS derivedtable1");
此处有更多详细信息:http://forums.oscommerce.com/topic/290110-class-splitpageresults/
在我的应用程序 (osCommerce) 中,我不得不修改如下所示的查询:
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 find_in_set(fap.filter_id,'126, 130')
ORDER BY p.products_date_added DESC,
pd.products_name
就这样结束,为了准确的结果:
AND fap.filter_id IN (126, 130)
GROUP BY p.products_id
HAVING COUNT(DISTINCT fap.filter_id) = 2;
我现在遇到的问题是以下查询正在使用这个新查询并给我错误的结果。
SELECT COUNT( DISTINCT p.products_id ) AS total
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
ORDER BY p.products_date_added DESC , pd.products_name
这不是给出原始查询中所有 product_id
计数的 1 行结果,而是现在给出多行结果(行数与预期的总产品数相同) 中的每个数字为 1。
主要问题似乎是 GROUP BY p.products_id
HAVING COUNT( DISTINCT fap.filter_id ) =2
有什么方法可以修改原始查询,使计数查询在仍然使用 AND fap.filter_id IN ( 126, 130 )
的同时仍能正常工作吗?
您需要使用子查询来获得您想要的结果:
select count(*)
from (<old query here>) s;
需要在product id级别进行聚合,才能得到符合原始条件的产品。计算此类产品的数量需要再次聚合。
正如 Gordon 所建议的,使用子查询通常应该可行。
由于此查询看起来像产品列表查询,并且由于您使用的是 osCommerce,因此当您修改查询以使用子查询时,您将遇到另一个核心问题:
分页结果的计数查询会失败,因为它不支持子查询。
要解决此问题,您还需要修改 catalog/includes/classes/split_page_results.php
变化:
$count_query = tep_db_query("select count(" . $count_string . ") as total " . substr($this->sql_query, $pos_from, ($pos_to - $pos_from)));
收件人:
$count_query = tep_db_query("select count(*) as total from (" . $this->sql_query . ") AS derivedtable1");
此处有更多详细信息:http://forums.oscommerce.com/topic/290110-class-splitpageresults/