我试图按销售量和日期获取产品清单。我还想显示尚未在列表中销售的产品,所以我尝试先做一个子查询,但是MYSQL给了我这样的信息:
操作数应包含1列
SELECT product.product_id,
product.product_brand_id,
product.product_model_id,
product.product_subcategory_id,
product.product_retail_price,
product.product_wholesale_price
FROM product
WHERE product.product_subcategory_id = $subcategory_id
AND (SELECT SUM(product_sold.product_quantity) AS product_quantity_sold,
SUM(product_sold.product_total_price) AS total_price_sold
FROM product
INNER JOIN product_sold
ON product.product_id = product_sold.product_id
INNER JOIN sales
ON sales.sales_id = product_sold.product_sales_id
WHERE sales.sales_approved = '1'
AND sales.sales_approved_time > '$start_timestamp'
AND sales.sales_approved_time < '$end_timestamp')
子查询不起作用,所以我尝试使用LEFT OUTER JOIN
按照其他成员的建议使用此查询:
SELECT product.product_id,
product.product_brand_id,
product.product_model_id,
product.product_subcategory_id,
product.product_retail_price,
product.product_wholesale_price,
SUM(product_sold.product_quantity) AS product_quantity_sold,
SUM(product_sold.product_total_price) AS total_price_sold
FROM product
LEFT OUTER JOIN product_sold ON product.product_id = product_sold.product_id
AND product.product_subcategory_id = $subcategory_id
LEFT OUTER JOIN sales ON sales.sales_id = product_sold.product_sales_id
WHERE sales.sales_approved = '1'
AND sales.sales_approved_time > '$start_timestamp'
AND sales.sales_approved_time < '$end_timestamp'
GROUP BY product.product_id
ORDER BY SUM(product_sold.product_quantity) DESC
但是LEFT OUTER JOIN
的这个查询只给我一个销售产品的清单,我想要的还是显示尚未在列表中销售的产品。
这是使用sqlfiddle.com /#!2 / 967ee
的架构答案 0 :(得分:1)
此查询将有效,从SELECT
产品表中的更多列添加到SELECT
和GROUP BY
子句:
SELECT p.product_id
,SUM(IFNULL(ps.product_quantity,0)) AS product_quantity_sold
,SUM(IFNULL(ps.product_total_price,0)) AS total_price_sold
FROM product p
LEFT JOIN product_sold ps ON p.product_id = ps.product_id
LEFT JOIN sales s ON ps.product_sales_id = s.sales_id
WHERE p.product_subcategory_id = $subcategory_id
AND ( s.sales_id IS NULL
OR ( s.sales_approved = '1'
AND s.sales_approved_time > '$start_timestamp'
AND s.sales_approved_time < '$end_timestamp'
)
)
GROUP BY p.product_id
ORDER BY SUM(IFNULL(ps.product_quantity,0)) DESC
<强>解释强>
如果您可以在product_sold_approved
子句中使用product_sold_approved_time
和WHERE
而不是sales表中的值,则此查询会更简单。
您LEFT JOIN product_sold
,LEFT JOIN
表示您保留products
表中的所有记录,而已售出的记录将加入每个product_sold
条记录。然后对sales
表执行相同的操作。
因此,在此阶段,您有很多行product + product_sold + sales
,但您还拥有所有未售出的产品product + NULL + NULL
。您需要过滤掉匹配的销售字段不符合条件的所有已加入记录,但您需要保留所有未能单独加入的记录。
要实现此目的,您需要一个WHERE子句,分别处理每组记录。 WHERE (condition A) OR (condition B)
。
条件A处理我们未售出的产品WHERE s.sales_id IS NULL
- 所有无法加入促销的记录都包含在结果集中,并且不必与其他条件匹配。
OR (sales_approved = 1 AND ... AND ...)
记录必须通过where子句的这一半,因此我们会过滤掉不需要的销售。
最后,我们留下了一个结果集,其中包含所有没有任何销售额的记录+所有符合您条件的产品/ product_sales /销售记录。然后我们可以只使用GROUP BY product_id和SUM剩下的内容。
我的SQL中有IFNULL
个,这是因为如果你总结了很多值,其中一些可能是NULL
,如果单个值是NULL
那么SUM
的结果为NULL
。 IFNULL(column,0)
通过将任何NULL
值转换为0
来防止这种情况发生。 1 + NULL = NULL
,1 + 0 = 1
。 HOWEVER ,在反思中我可能不需要查询 - 删除它们,您应该注意到更改。