【问题标题】:Select distinct rows based on some, but not all columns根据一些(但不是所有)列选择不同的行
【发布时间】:2011-03-30 03:38:44
【问题描述】:

我最初在处理从分组结果中选择某些聚合值(最小值、最大值等)的 SQL 查询时遇到了这个问题。例如,从每个水果组中选择最便宜的水果、品种和价格。常见的解决方案是首先使用 MIN 将水果与最便宜的价格一起分组,然后自行加入它以获得另一列(在本例中为“品种”)。

现在假设我们有多个相同价格的水果品种,而那个价格恰好是最低价格。所以我们最终得到这样的结果:

Apple    Fuji         5.00
Apple    Green        5.00
Orange   valencia     3.00
Pear     bradford     6.00

如何才能使最终结果中只出现一种苹果?它可以是任何一个品种,无论是出现第一个、最后一个还是随机出现的记录。

所以基本上我需要根据三列中的两列相等来消除行,只要最终结果集中还剩下一列,消除哪些行并不重要。

任何帮助将不胜感激。

【问题讨论】:

  • 你能粘贴你原来的查询吗?

标签: sql linq-to-sql frameworks entity


【解决方案1】:

试试这个...我加了更多水果。阅读的方法是从最里面的From子句开始,然后找出路。

    create table fruit (
        FruitName varchar(50) not null,
        FruitVariety varchar(50) not null,
        Price decimal(10,2) not null
    )

    insert into fruit (FruitName, FruitVariety, Price)
    values ('Apple','Fuji',5.00)
    insert into fruit (FruitName, FruitVariety, Price)
    values ('Apple','Green',5.00)
    insert into fruit (FruitName, FruitVariety, Price)
    values ('Orange','Valencia',3.00)
    insert into fruit (FruitName, FruitVariety, Price)
    values ('Orange','Navel',5.00)
    insert into fruit (FruitName, FruitVariety, Price)
    values ('Pear','Bradford',6.00)
    insert into fruit (FruitName, FruitVariety, Price)
    values ('Pear','Nashi',8.00)

    select 
        rankedCheapFruits.FruitName,
        rankedCheapFruits.FruitVariety,
        rankedCheapFruits.Price
    from (
        select 
            f.FruitName,
            f.FruitVariety,
            f.Price,
            row_number() over(
                partition by f.FruitName
                order by f.FruitName, f.FruitVariety
                ) as FruitRank
        from (
            select 
                f.FruitName, 
                min(f.Price) as LowestPrice
            from   Fruit f
            group by 
                f.FruitName
            ) as cheapFruits
            join Fruit f on cheapFruits.FruitName = f.FruitName
                and f.Price = cheapFruits.LowestPrice
        ) rankedCheapFruits
    where rankedCheapFruits.FruitRank = 1

【讨论】:

    【解决方案2】:

    您可以使用 MIN 运算符,这会将其限制在第一行

    【讨论】:

    • Min 本身会将每个组限制为一行,但是当连接回原始表以获取另一列时(在 id = id 和 price = price 上),它将产生两行,因为有最低价格相同的两个品种。所以我的问题是如何防止这种情况发生。
    【解决方案3】:

    一种选择是根据某些标准(水果品种的字母顺序)对行进行排名,然后选择排名中的最小值。

    ms-sql 中有一个 rank() 函数正是为了这个目的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 2014-03-11
      • 2017-06-17
      • 2019-02-06
      • 1970-01-01
      • 2021-12-17
      相关资源
      最近更新 更多