获取一列的最小值,但选择多列

0s7z1bwu  于 2021-07-26  发布在  Java
关注(0)|答案(3)|浏览(267)

我有一张table如下:

ID     NAME     AMOUNT
______________________
 1      A          3
 1      B          4
 2      C          18
 4      I          2 
 4      P          9

我想要每个id的最小值(amount),但是我仍然想显示它的名称。所以我想要这个:

ID     NAME     min(AMOUNT)
______________________
 1      A          3
 2      C          18
 4      I          2

id也可以出现多次。我试过这个:

SELECT ID, NAME, min(AMOUNT) FROM TABLE
GROUP BY ID

但这当然是个错误,因为我必须

GROUP BY ID, NAME

但后来我

ID     NAME     AMOUNT
______________________
 1      A          3
 1      B          4
 2      C          18
 4      I          2 
 4      P          9

我明白为什么,它会为id+name的每个组合寻找最小值(amount)。所以我的问题基本上是,如何选择多个列(id、name、amount)并只获得一个列的最小值,而仍然显示其他列?
我是sql新手,但似乎找不到答案。。

xbp102n0

xbp102n01#

如果您使用的是postgresql、sqlserver、mysql 8.0和oracle,那么可以使用window函数尝试以下操作 row_number() .
如果你有一个相同数量的身份证,那么你可以使用 dense_rank() 而不是 row_number() 这是演示。

select
    id,
    name,
    amount
from
(
    select
        *,
        row_number() over (partition by id order by amount) as rnk
    from yourTable
) val
where rnk = 1

输出:

| id  | name | amount |
| --- | ---- | ------ |
| 1   | A    | 3      |
| 2   | C    | 18     |
| 4   | I    | 2      |

不使用窗口功能的第二个选项

select
    val.id,
    t.name,
    val.amount
from myTable t
join
(
  select
        id,
        min(amount) as amount
    from myTable
    group by
        id
) val
on t.id = val.id
and t.amount = val.amount
hgc7kmma

hgc7kmma2#

您没有指定数据库供应商。如果幸运的是postgres,这个问题也可以解决,而不必使用专有的嵌套子查询 distinct on 条款:

with t(id,name,amount) as (values
 (1,      'A',          3),
 (1,      'B',          4),
 (1,      'W',          3),
 (2,      'C',          18),
 (4,      'I',          2),
 (4,      'P',          9)
)
select distinct on (id, name_of_min) id 
     , first_value(name) over (partition by id order by amount) as name_of_min
     , amount
from t
order by id, name_of_min

只是为了扩大知识面。我不建议使用专有功能。 first_value 是标准函数,但要解决简单查询中的问题还是不够的@“热心”的回答是完美的。

e4eetjau

e4eetjau3#

在许多数据库中,最有效的方法是使用相关子查询:

select t.*
from t
where t.amount = (select min(t2.amount) from t t2 where t2.id = t.id);

特别是,这可以利用 (id, amount) .

相关问题