找到正确的“记录”并仅使用该记录中的数据

时间:2013-09-07 17:22:17

标签: sql

我有一份产品和供应商清单。 我需要确保数量大于零。 如果是这样,我需要找到价格最低的产品并列出供应商,产品(SKU),数量和价格。

我的测试数据架构是:

create table products(merchant varchar(100), name varchar(150), quantity int, totalprice int);

insert into products values
  ('Supplier A', 'APC-SMT1000I', 10, 150),
  ('Supplier B', 'APC-SMT1000I', 15, 250), 
  ('Supplier C', 'APC-SMT1000I', 15, 350), 
  ('Supplier D', 'DEF-SMT1000I', 10, 500), 
  ('Supplier E', 'DEF-SMT1000I', 35, 350), 
  ('Supplier G', 'GHI-SMT1000I', 75, 70)

逻辑上,我希望结果如下:

SUPPLIER    SKU          QTY        PRICE
Supplier A  APC-SMT1000I     10       150
Supplier D  DEF-SMT1000I     35           350
Supplier G  GHI-SMT1000I     75        70

我的SQL语句如下:

SELECT merchant AS Supplier, name AS sku,quantity AS Qty, 
min(totalprice) AS Price FROM products where quantity > 0 group by name;

我的结果是:

SUPPLIER    SKU          QTY        PRICE
Supplier A  APC-SMT1000I     10       150
Supplier D  DEF-SMT1000I     10           350
Supplier G  GHI-SMT1000I     75        70

显然,编码是找到最低价格并显示它,但没有正确的数据。

我的问题? 如何对数据进行分组,找到价格最低的record,并确保程序仅使用该记录中的数据?

3 个答案:

答案 0 :(得分:3)

您可以使用以下查询:

SELECT products.*
FROM
  products INNER JOIN
  (SELECT name, MIN(totalprice) min_price
   FROM products
   WHERE quantity>0
   GROUP BY name) m
  ON products.name=m.name AND products.totalprice=min_price

在子查询中,我计算每个名称的最小总价,然后我将此子查询与products表一起加入,以仅返回具有该名称的最小总价的行。如果有多行具有最低价格,则会显示所有行。

请参阅小提琴here

答案 1 :(得分:3)

最简单的方法是使用窗口/分析函数。您没有具体使用您正在使用的数据库,但这是大多数(但不是所有)数据库中可用的ANSI标准功能。

以下是语法:

select merchant AS Supplier, name AS sku, quantity AS Qty, 
       totalprice AS Price
from (select p.*,
             row_number() over (partition by name
                                order by totalprice
                               ) as seqnum
      from products p
      where quantity > 0
     ) p
where seqnum = 1;

答案 2 :(得分:2)

您尚未指定RDBMS,因此我将提供一些查询。
这个应该在任何数据库中工作(但需要2个表扫描):

select
    p.merchant as Supplier,
    p.name as sku,
    p.quantity as Qty, 
    p.totalprice as Price
from products as p
where
    p.totalprice in
    (
         select min(t.totalprice)
         from products as t
         where t.name = p.name
    )

这个应该适用于任何具有row_number窗口函数的RDBMS:

with cte as (
    select *, row_number() over(partition by name order by totalprice) as rn
    from products
)
select
    p.merchant as Supplier,
    p.name as sku,
    p.quantity as Qty, 
    p.totalprice as Price
from cte as p
where rn = 1

这个是PostgreSQL:

select distinct on (p.name)
    p.merchant as Supplier,
    p.name as sku,
    p.quantity as Qty, 
    p.totalprice as Price
from products as p
order by p.name, p.totalprice

<强> =&GT; sql fiddle demo