-2

我是 PostgreSQL 新手,我通过几个例子来学习!

我正在解决 PostgreSQL 中的一个查询,我来的很少,但在某一时刻被卡住了!

鉴于下面 SQLFiddle 中的示例数据,我尝试了:

--6.find most sold product with  with sales_id, product_name,quantity and sum(price)

select array_agg(s.sale_id),p.product_name,s.quantity,sum(s.price)
from products p
join sales s
on p.product_id=s.product_id;

但它失败了:

ERROR: column "p.product_name" must appear in the GROUP BY clause or be used in an aggregate function:

这是带有示例数据的SQL Fiddle 。

我正在使用 PostgreSQL 9.2。

4

3 回答 3

2

问题#6的查询解决方案是::

 select array_agg(s.sale_id),p.product_name,sum(s.quantity) as Quantity ,sum(s.price) as Total_Price
    from sales s,products p
    where s.product_id =p.product_id 
    group by p.product_id  
    order by sum(s.quantity) desc limit 1  ;

评论他人

问题#9:@Robin Hood 的

select s.sale_id,p.product_name,s.quantity,s.price 
from products p,sales s
 where p.product_id=s.product_id and p.product_name LIKE 'S%';

“S%”是区分大小写的..所以它是如何工作的..

问题#10:@Robin Hood 的

存储过程是:

CREATE OR REPLACE FUNCTION get_details()
  RETURNS TABLE(sale_id integer,product_name varchar,quantity integer,price int) AS
$BODY$
BEGIN
    RETURN QUERY
    select s.sale_id,p.product_name,s.quantity,s.price 
    from products p 
    join  sales s
    on p.product_id =s.product_id ;

    Exception WHEN no_data_found then
RAISE NOTICE 'No data available';
    END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

从 get_details() 中选择 *;然后你会得到结果。

于 2013-07-24T06:53:01.550 回答
2

尽管看起来很简单,但这是一个非常有趣的问题。

未解决的#6

这有两个阶段:

  1. 找到最畅销的产品;和
  2. 显示该产品所需的详细信息

问题写得不好;它无法指定您是想要销售额最多的产品,还是美元销售额最高的产品。我将假设前者,但很容易将以下查询改为按总价排序。

更新:@user2561626 找到了我提到的简单解决方案,我确信我忽略了但无法想到:http ://sqlfiddle.com/#!12/dbe7c/118 。然后使用结果集SUM的输出。ORDER BYLIMIT

以下是我尝试过的复杂而迂回的方式,因为我想不出简单的方式:

一种方法是使用带有 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_idsalesNULL2 NOT IN (1, NULL)NULLWHERE

最好将其重新表述为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_truncextract. 这不是你的错,这是问题中糟糕的表格设计。这个问题也可以更清楚;我认为你已经正确回答了书面问题,但他们没有说是否应该显示没有销售的年份 - 大概他们认为没有。如果有,您必须在一个generate_series日期上进行左外连接,以将空年份填零。

坦率地说,问题 #8 是另一个糟糕的问题。“最高价格”。嗯。什么?“每件商品支付的最高价格”将是“价格/数量”。“每种产品的最大总个人销售价值”就是您所写的。这个问题似乎允许任何一个。

于 2013-07-23T06:25:07.147 回答
1

我什至需要帮助解决这些问题!我只想将这些查询添加到。

--问题#9

--9. select product details with sales_id, product_name,quantity and price those product names are started with letter ‘s’

--This selects my product details   

 select s.sale_id,p.product_name,s.quantity,s.price
    from products p,sales s
    where p.product_id=s.product_id ;

--This is'nt working to find those names which start with s.. is there any other way to solve this..
 select s.sale_id,p.product_name,s.quantity,s.price
    from products p,sales s
    where p.product_id=s.product_id and product_name = 's%';

--10。编写存储过程以提取所有销售和产品详细信息,其中包含 sales_id、product_name、数量和价格,并进行异常处理并发出通知

于 2013-07-23T07:55:52.997 回答