【问题标题】:How to select records with minimum price per group如何选择每组价格最低的记录
【发布时间】:2014-11-13 00:02:47
【问题描述】:

我想选择数据库中的每一对两列,但只选择价格最低的条目。因此,我想输出idprice 列。

但它不起作用:

我的桌子:

id | category | type | name | price
1;"car";"pkw";"honda";1000.00
2;"car";"pkw";"bmw";2000.00

SQL:

select min(price) price, id
from cartable
group by category, type

结果: Column "cartable.id" must be present in GROUP-BY clause or used in an aggregate function.

【问题讨论】:

  • cartable.id 添加到组的末尾。这是 sql 不喜欢的那些奇怪的事情之一
  • 好吧,但我不想按 ID 分组!
  • @jbutler483 我不会说这很奇怪,但很明智。事实上,我认为 MySQL 不需要这个是脑残。
  • 如果您不打算按 ID 分组,那为什么它会在选择列表中?
  • 你使用什么数据库?

标签: sql database postgresql greatest-n-per-group


【解决方案1】:

如果您想要最低价格的条目,则计算最低价格并将信息重新加入:

select ct.*
from cartable ct join
     (select category, type, min(price) as price
      from cartable
      group by category, type
     ) ctp
     on ct.category = ctp.category and ct.type = ctp.type and ct.price = ctp.price;

【讨论】:

    【解决方案2】:

    您可以使用 EXISTS 子句来实现:

    SELECT * 
    FROM  cartable ct 
    WHERE 
      NOT EXISTS (
               SELECT * 
               FROM  cartable 
               WHERE ct.type = type and ct.category = categoery and ct.price < price)
    

    对于速度caparison,你可以试试这个:

    SELECT DISTINCT ON (type, category), id, price
    FROM cartable
    ORDER BY price DESC
    

    【讨论】:

    【解决方案3】:
    SELECT id, price
    from  cartable C
    inner join
    (
    select min(price) as price , category, type
    from cartable
    group by category, type
    )T
    on T.category = C.category
    and T.type = C.type
    

    【讨论】:

      【解决方案4】:

      大多数时候,除了决心使用Select - Over之外,你别无他法

      select price, id
      from(
          select price, id, [rnk] = ROW_NUMBER() over( partition by category, type order by price)
          from cartable
      ) as a
      where [rnk]=1
      

      适当创建索引,性能不错。

      在你的例子中是这样的:

      CREATE NONCLUSTERED INDEX [foo]
      ON [dbo].[cartable] ([category],[type])
      INCLUDE ([price])
      

      【讨论】:

        【解决方案5】:

        也许你可以试试:

        select id, price from cartable 
        where price = (select min(price) from cartable);
        

        【讨论】:

          猜你喜欢
          • 2018-03-16
          • 1970-01-01
          • 1970-01-01
          • 2016-03-11
          • 2016-03-18
          • 2018-04-26
          • 1970-01-01
          • 2017-12-10
          • 1970-01-01
          相关资源
          最近更新 更多