尽管看起来很简单,但这是一个非常有趣的问题。
未解决的#6
这有两个阶段:
- 找到最畅销的产品;和
- 显示该产品所需的详细信息
问题写得不好;它无法指定您是想要销售额最多的产品,还是美元销售额最高的产品。我将假设前者,但很容易将以下查询改为按总价排序。
更新:@user2561626 找到了我提到的简单解决方案,我确信我忽略了但无法想到:http ://sqlfiddle.com/#!12/dbe7c/118 。然后使用结果集SUM
的输出。ORDER BY
LIMIT
以下是我尝试过的复杂而迂回的方式,因为我想不出简单的方式:
一种方法是使用带有 an 的子查询,ORDER BY
并按LIMIT
总销售额对产品进行排序,然后选择排名靠前的产品。然后加入该内部查询以生成所需的产品摘要。在这种情况下,我加入了两次销售,一次在内部查询中,一次在外部查询中,我只计算一种产品的更多详细信息。在内部查询中只加入一次并做更多工作可能更有效,但这将涉及创建和丢弃更大的结果集,因此您可以根据数据分布进行调整。
SELECT
array_agg(s.sale_id) AS sales_ids,
(SELECT p.product_name FROM products p WHERE p.product_id = pp.product_id) AS product_name,
sum(s.quantity) AS total_quantity,
sum(s.price) AS total_price
FROM
(
-- Find the product with the largest number of sales
-- If multiple products have the same sales an arbitrary candidate
-- is selected; extend the ORDER BY if you want to control which
-- one gets picked.
SELECT
s2.product_id, sum(s2.quantity) AS total_quantity
FROM sales s2
GROUP BY s2.product_id
ORDER BY 2 DESC
LIMIT 1
) AS pp
INNER JOIN sales s ON (pp.product_id = s.product_id)
GROUP BY s.product_id, pp.product_id;
老实说,我不太确定如何用纯粹的标准 SQL(即无LIMIT
子句)来表达这一点。您可以在子查询中使用 CTE 或多次扫描来查找最大销量和销量最高的产品 ID,但如果您有多个具有相同销量的产品,则会为您提供多个结果。
我不禁觉得我已经完全忘记了简单而明显的方法。
对他人的评论:
--1.write the query find the products which are not soled
select *
from products
where product_id not in (select distinct PRODUCT_ID from sales );
您的解决方案有点不正确,因为in没有NOT NULL
限制。它构建一个列表,然后在列表上进行过滤,但该列表可能包含, 和is ,这被视为 false。product_id
sales
NULL
2 NOT IN (1, NULL)
NULL
WHERE
最好将其重新表述为WHERE NOT EXISTS (SELECT 1 FROM sales s WHERE s.product_id = products.product_id)
.
使用 #2 再次更好地使用EXISTS
,但 PostgreSQL 可以自动将其优化为更好的形式,因为它在语义上是相同的;这个NULL
问题不适用IN
,只有NOT IN
。所以你的查询很好。
问题 #7 强调这是一个糟糕的模式。你不应该像这样存储拆分的年/月/日;一次销售将只有一个timestamptz
字段,并获得您使用的年份date_trunc
或extract
. 这不是你的错,这是问题中糟糕的表格设计。这个问题也可以更清楚;我认为你已经正确回答了书面问题,但他们没有说是否应该显示没有销售的年份 - 大概他们认为没有。如果有,您必须在一个generate_series
日期上进行左外连接,以将空年份填零。
坦率地说,问题 #8 是另一个糟糕的问题。“最高价格”。嗯。什么?“每件商品支付的最高价格”将是“价格/数量”。“每种产品的最大总个人销售价值”就是您所写的。这个问题似乎允许任何一个。