【问题标题】:T-Sql select and group by MIN()T-Sql 按 MIN() 选择和分组
【发布时间】:2016-07-31 18:27:34
【问题描述】:

我有 3 个表格,例如:

ProductCategory [1 - m] Product [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+

【问题讨论】:

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


    【解决方案1】:

    你可以使用像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

    【讨论】:

      【解决方案2】:

      如果您需要每个 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)
      

      【讨论】:

        【解决方案3】:

        您没有在查询中使用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;
        

        【讨论】:

          猜你喜欢
          • 2021-05-06
          • 1970-01-01
          • 1970-01-01
          • 2015-07-04
          • 1970-01-01
          • 2013-01-28
          • 2011-07-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多