我有3张表:
ProductCategory [1 - m] 产品 [1-m] ProductPrice
这样一个简单的脚本:
select pc.CategoryId ,pp.LanguageId , pp.ProductId ,pp.Price
from ProductCategory as pc
inner join Product as p on pc.ProductId = p.Id
inner join ProductPrice as pp on p.Id = pp.ProductId
order by CategoryId , LanguageId , ProductId
显示了这些表格数据:
CategoryId LanguageId ProductId Price
----------- ----------- ----------- ---------------------------------------
1 1 1 55.00
1 1 2 55.00
1 2 1 66.00
1 2 2 42.00
2 1 3 76.00
2 1 4 32.00
2 2 3 89.00
2 2 4 65.00
4 1 4 32.00
4 1 5 77.00
4 2 4 65.00
4 2 5 85.00
现在我需要的是: 对于每个类别,按获取完整行,但仅限于具有最低价格的产品。
我刚写了一个简单的查询,就像这样:
with dbData as
(
select pc.CategoryId ,pp.LanguageId , pp.ProductId ,pp.Price
from ProductCategory as pc
inner join Product as p on pc.ProductId = p.Id
inner join ProductPrice as pp on p.Id = pp.ProductId
)
select distinct db1.*
from dbData as db1
inner join dbData as db2 on db1.CategoryId = db2.CategoryId
where db1.LanguageId = db2.LanguageId
and db1.Price = (select Min(Price)
from dbData
where CategoryId = db2.CategoryId
and LanguageId = db2.LanguageId)
,结果是正确的:
CategoryId LanguageId ProductId Price
----------- ----------- ----------- ---------------------------------------
1 1 1 55.00
1 1 2 55.00
1 2 2 42.00
2 1 4 32.00
2 2 4 65.00
4 1 4 32.00
4 2 4 65.00
有没有更酷的方法呢?
注意:查询必须符合 Sql-Server 2008 R2 +
答案 0 :(得分:2)
您可以使用RANK()
等窗口函数:
WITH cte AS
(
select pc.CategoryId, pp.LanguageId, pp.ProductId, pp.Price,
rnk = RANK() OVER(PARTITION BY pc.CategoryId ,pp.LanguageId ORDER BY pp.Price)
from ProductCategory as pc
join Product as p on pc.ProductId = p.Id
join ProductPrice as pp on p.Id = pp.ProductId
)
SELECT CategoryId, LanguageId, ProductId, Price
FROM cte
WHERE rnk = 1;
的 LiveDemo
强>
答案 1 :(得分:0)
如果您需要按categoryid和languageid
的产品价格,可以将languageid添加到分区select top 1 with ties pc.CategoryId ,pp.LanguageId , pp.ProductId ,pp.Price
from ProductCategory as pc
inner join Product as p on pc.ProductId = p.Id
inner join ProductPrice as pp on p.Id = pp.ProductId
order by row_number() over (partition by pc.categoryid order by price)
答案 2 :(得分:0)
您没有在查询中使用Product
表,因此似乎没有必要。我想对此:
select ppc.*
from (select pc.CategoryId, pp.LanguageId , pp.ProductId, pp.Price,
row_number() over (partition by pc.CategoryId order by pp.Price) as seqnum
from ProductCategory pc inner join
ProductPrice pp
on pc.ProductId = pp.ProductId
) ppc
where seqnum = 1
order by CategoryId, LanguageId, ProductId;