我有一个看似微不足道的问题,但我无法使其发挥作用。它在Oracle SQL中。 以下是脚本示例:
create table product (
product_id number primary key,
name varchar(255)
);
create table producer (
producer_id number primary key,
name varchar(255)
);
create table catalog (
pp_product_id number,
pp_producer_id number,
price number
);
alter table catalog add constraint pp_product_id1 foreign key (pp_product_id) references product (product_id);
alter table catalog add constraint pp_product_id2 foreign key (pp_producer_id) references producer (producer_id);
insert into product (product_id, name) values (1, 'HDD 250 gb');
insert into product (product_id, name) values (2, 'HDD 500 gb');
insert into product (product_id, name) values (3, 'HDD 750 gb');
insert into producer (producer_id, name) values (1, 'Hitachi');
insert into producer (producer_id, name) values (2, 'Corsair');
insert into producer (producer_id, name) values (3, 'Western Digital');
insert into catalog (pp_product_id, pp_producer_id, price) values (1,1, 80);
insert into catalog (pp_product_id, pp_producer_id, price) values (1,3, 60);
insert into catalog (pp_product_id, pp_producer_id, price) values (2,1, 75);
insert into catalog (pp_product_id, pp_producer_id, price) values (2,2, 40);
insert into catalog (pp_product_id, pp_producer_id, price) values (3,2, 63);
insert into catalog (pp_product_id, pp_producer_id, price) values (3,3, 100);
因此,共有6种产品,3种生产商,3种产品(HD类型)。我需要的是显示产品的CHEAPEST,每种产品类型与该产品相关的生产者名称。类似的东西:
Western Digital 250 gb 60
Corsair 500 gb 40
Corsair 750 gb 63
这将在他们的组中选择最便宜的HD(类型)
select p.name, min (c.price)
from product p, catalog c, producer prc
where c.pp_product_id = p.product_id and prc.producer_id = c.pp_producer_id
group by p.name;
...但我不能添加生产者名称?我尝试了几种解决方案,但都没有。
答案 0 :(得分:2)
这应该回答你的核心问题。该帖子解决了MySQL中的问题,但适用相同的概念。
http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
一旦你获得该组中的最低价格产品,剩下的就是加入。
答案 1 :(得分:2)
这对row_number()
很有用。您的数据没有type
字段,因此我在产品表中发明了一个:
select *
from (select p.name as product_name, p.type, prod.name as producer_name,
price,
ROW_NUMBER() over (partition by p.name order by price ) as seqnum
from catalog c join
product p
on c.pp_product_id = p.product_id join
producer prod
on c.pp_producer_id = prod.producer_id
) t
where seqnum = 1;
如果您想要所有产品的最低价格,请使用以下轻微变化:
select *
from (select p.name as product_name, p.type, prod.name as producer_name,
price,
min(price) over (partition by p.name) as minprice
from catalog c join
product p
on c.pp_product_id = p.product_id join
producer prod
on c.pp_producer_id = prod.producer_id
) t
where price = minprice;
答案 2 :(得分:1)
感谢@Gordon Linoff - 他的代码略有改动,它适用于我的问题。为了清楚起见,我在这里发布解决方案:
select *
from (select p.name as product_name, prod.name as producer_name,price,
ROW_NUMBER() over (partition by p.name order by price ) as seqnum
from catalog c join
product p
on c.pp_product_id = p.product_id join
producer prod
on c.pp_producer_id = prod.producer_id
) t
where seqnum = 1;
答案 3 :(得分:0)
与此同时,我找到了另一个可能的答案:
SELECT p.name, pr.name, c2.minprice
FROM product p, producer pr, catalog c,
(SELECT pp_product_id, MIN(price) AS minprice
FROM catalog c1
GROUP BY pp_product_id
) c2
WHERE p.product_id=c.pp_product_id
AND pr.producer_id=c.pp_producer_id
AND p.product_id =c2.pp_product_id
AND c.price =c2.minprice;
输出如下:
HDD 750 gb Corsair 6300
HDD 500 gb Corsair 4000
HDD 250 gb Western Digital 6000