2017-06-28 17 views
1

テーブルは次のようになります。1つの列に最大値を持つ行を選択するためのSQLクエリの作成方法

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 

これは私が望む結果です。

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 

ターゲットは、最も高いRef per Idであり、Order Date descで注文されます。

pl/sqlを使用してSQLクエリを作成する方法について教えてください。

+1

あなたがするように求められたびに「最高」または「最低」に関する問題を解決するには、重複(ネクタイ)について考える必要があります。 Antの両方の行がRef = 300の場合はどうなりますか?どちらが「最高」ですか?結果に両方の行を含める必要がありますか?または、最新の日付のものだけを取る?または、Ref列に重複がありませんか?その後、日付で結果を注文するとき - 2つの日付が等しい場合、どのようにネクタイを壊すのですか? – mathguy

答えて

0

あなたは別でグループ化された1列の最大または最小を、必要とする要件のこの

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 
-1
SELECT Id, Name, Max(Ref) as Ref, Min(`Date`) as `Date` 
From Forge 
Group By Id, Name 
Order by Min(`Date`) desc; 
+3

これはOracleのようには見えません.Oracleではバッククックがありません。それを修正した後、クエリはOPが望んでいたものではなく、ある行からの最大値(ref)と別の行からの最小値(date)を選択します。 – mathguy

1

この種を(使用できますが、最大または最小の行からすべてのデータを必要とします)は、ほとんどの解析関数が対象です。私は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 
0

自己のもう一つの解決策は、(:How can I SELECT rows with MAX(Column value), DISTINCT by another column in 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 
0

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; 
関連する問題