T-Sql按MIN()

时间:2016-04-10 19:16:23

标签: sql sql-server sql-server-2008 tsql greatest-n-per-group

我有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 +

3 个答案:

答案 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;