简体   繁体   English

如何编写sql查询以选择一列中具有最大值的行

[英]how to write sql query to select rows with max value in one column

My Table looks like this. 我的表看起来像这样。

Id   |  Name  |  Ref  | Date        | From
10   |  Ant   |  100  | 2017-02-02  | David
10   |  Ant   |  300  | 2016-01-01  | David
2    |  Cat   |  90   | 2017-09-09  | David
2    |  Cat   |  500  | 2016-02-03  | David
3    |  Bird  |  150  | 2017-06-28  | David

This is the result I want. 这是我想要的结果。

Id   |  Name  |  Ref  | Date       | From
3    |  Bird  |  150  | 2017-06-28 | David
2    |  Cat   |  500  | 2016-02-03 | David
10   |  Ant   |  300  | 2016-01-01 | David

My target is the highest Ref per Id, ordered by Order Date desc. 我的目标是按订单日期desc排序的最高每个Id的参考。

Could you please tell me about how to write a sql query using pl/sql. 能否告诉我如何使用pl / sql编写SQL查询。

This kind of requirement (where you need the max or min by one column, grouped by another, but you need all the data from the max or min row) is pretty much what analytic functions are for. 这种要求(您需要最多或最少一列,按另一列分组,但您需要来自最大或最小行的所有数据)几乎是分析函数的用途。 I used row_number - if ties are possible, you need to clarify the assignment (see my Comment under your question), and depending on the details, another analytic function may be more appropriate - perhaps rank() . 我使用了row_number - 如果关系是可能的,你需要澄清分配(参见我的问题下的评论),并且根据细节,另一个分析函数可能更合适 - 也许是rank()

with
     my_table ( id, name, ref, dt, frm ) as (
       select 10, 'Ant' , 100, date '2017-02-02', 'David' from dual union all
       select 10, 'Ant' , 300, date '2016-01-01', 'David' from dual union all
       select  2, 'Cat' ,  90, date '2017-09-09', 'David' from dual union all
       select  2, 'Cat' , 500, date '2016-02-03', 'David' from dual union all
       select  3, 'Bird', 150, date '2017-06-28', 'David' from dual
     )
-- End of simulated table (for testing purposes only, not part of the solution).
-- SQL query begins BELOW THIS LINE.
select   id, name, ref, dt, frm
from     (
           select id, name, ref, dt, frm,
                  row_number() over (partition by id order by ref desc, dt desc) as rn
           from   my_table
         )
where    rn = 1
order by dt desc
;

ID  NAME  REF  DT          FRM 
--  ----  ---  ----------  -----
 3  Bird  150  2017-06-28  David
 2  Cat   500  2016-02-03  David
10  Ant   300  2016-01-01  David

You can use this 你可以用它

SELECT
Id
,Name
,Ref
,[Date]
FROM(
SELECT 
* 
, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Ref DESC) AS Row#
FROM yourtable
) A WHERE Row# = 1
ORDER BY A.[Date] DESC

Another solution with a self join (Idea came from here: How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL? ): 另一个带有自联接的解决方案(Idea来自这里: 我如何用MAX(列值)选择行,DISTINCT用SQL中的另一列? ):

with
    my_table ( id, name, ref, dt, frm ) as (
      select 10, 'Ant' , 100, date '2017-02-02', 'David' from dual union all
      select 10, 'Ant' , 300, date '2016-01-01', 'David' from dual union all
      select 10, 'Ant' , 300, date '2015-01-01', 'David' from dual union all
      select  2, 'Cat' ,  90, date '2017-09-09', 'David' from dual union all
      select  2, 'Cat' , 500, date '2016-02-03', 'David' from dual union all
      select  3, 'Bird', 150, date '2017-06-28', 'David' from dual
    )
-- End of simulated table (for testing purposes only, not part of the solution).
-- SQL query begins BELOW THIS LINE.

select m1.* 
from my_table m1 
left join my_table m2 
on m1.id = m2.id and (
 -- this is basically a comparator: order by ref desc, dt desc
 m1.ref < m2.ref or (
   m1.ref = m2.ref and 
   m1.dt < m2.dt
 )
) where m2.id is null order by m1.dt desc
;

        ID NAME        REF DT        FRM 
---------- ---- ---------- --------- -----
         3 Bird        150 28-JUN-17 David
         2 Cat         500 03-FEB-16 David
        10 Ant         300 01-JAN-16 David

Use the "better than" SQL principal: 使用“优于”SQL主体:

select a.Id, a.Name, a.Ref, a.Dt, a.frm
from table_name a
left join table_name b on a.id = b.id and b.ref > a.ref -- b.ref > a.ref would make b.ref "better" that a
where b.id is null -- Now check and make sure there is nothing "better"
group by a.id;
SELECT Id, Name, Max(Ref) as Ref, Min(`Date`) as `Date`
From Forge
Group By Id, Name
Order by Min(`Date`) desc;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM