2017-11-21 16 views
-2

ユーザーごとに最大行を選択:のOracle SQLは - 私はこのようなテーブル持って

PROFILE_ID X_START_DATE X_END_DATE FORMER_EMPLOYER NEW_EMPLOYER START_DATE 
1   2015-07-20 2016-07-20 GOOGLE    BURGER KING 2017-01-01 
1   2003-10-25 2009-01-14 FACEBOOK   BURGER KING 2017-01-01 
2   2007-10-04 2008-05-05 MICHAELS   KFC   2017-01-01 
2   2008-05-06 2009-05-05 GOOGLE    KFC   2017-01-01 
2   2009-05-06 2010-05-05 FACEBOOK   KFC   2017-01-01 
3   2007-10-04 2008-05-05 MCDONALDS   BURGER KING 2017-01-01 

私が欲しいもの:各PROFILE_IDに対して

を、私は最新のX_END_DATEを含む行を、必要とします。 PROFILE_ID 1の場合、私は1行などが必要です。

私は:

Select profile_id, max(end_date) 
group by 1; 

が、私は実際に私が欲しいものを得るではなく、私が必要とするすべての列。列数を増やすことで、私は "groupby"ステートメントでそれらを使用する必要があります。これは私が望むものではありません。

ありがとうございます! Oracleで

答えて

1

INを使用して別の方法とサブクエリ

select * 
from yourtable 
where (profile_id, end_date) IN 
(Select profile_id, max(end_date) as end_date 
from yourtable 
group by profile_id); 

ご希望の場合は、あなたが行のどのデータを確実にするために、他のすべての列に集約関数を指定する必要があり、グループを使用している場合

select a.* 
from yourtable a 
INNER JOIN (Select profile_id, max(end_date) as end_date 
      from yourtable 
      group by profile_id) b 
ON a.profile_id = b.profile_id and a.end_date b.end_date; 
+0

私は手で入力するよりも長いリストのためにINを使用しないでください。これは合理的に2つのテーブルスキャンを必要とするかもしれません.1つはグループ用、もう1つはINフィルタ用です。分析を行うには通常1回のスキャンしか必要ありません。大きなテーブルでは大きなパフォーマンス向上が得られます –

+0

あなたは私が別の可能性を含んでいる一方通行に答えました。 JOIN – SriniV

+0

でGROUP BY profile_idを実行すると、クエリがANSI/ISO SQLに準拠します。 – jarlh

0

が、これは最も簡単な解析関数と呼ばれるものを使用して行われます。それが動作する方法がある

SELECT * FROM 
    (
    SELECT 
    t.*, 
    ROW_NUMBER() OVER(PARTITION BY t.profile_id ORDER BY t.end_date DESC) as rown 
    FROM 
    yourtable t 
) a 
    WHERE rown = 1 

、ROW_NUMBER関数は、パーティション内の行のブロックに増分番号を割り当て - すべての行で同じパーティション(同じプロファイルID)が番号付けのために考慮されます。行の順序はend_dateの降順で指定します(最近の最初の値です)。これにより、最後のend_dateの値に常に1という番号が付けられます。

0

に参加しますあなたはポップしたい氷。

グループを覚えていると、適用された列のレコードが1つだけ表示されます。

Select profile_id, max(end_date), 
max(X_END_DATE), 
max(FORMER_EMPLOYER),  
max(NEW_EMPLOYER), 
max(START_DATE) 
group by profile_id; 

集計関数を追加するだけで、不要な列をすべてグループに追加する必要はありません。

+1

'GROUP BY 1 'は最初の列ではなく、数値リテラル' 1 'でグループ化されます。また、最大開始日が最大終了日とは異なる行にあり、他の列でも同じ行から最大値を得ることはできません。 – MT0

+0

MT0、提案をいただきありがとうございます。列名に変更しました。 –

+0

'MAX'を使うつもりならば、非終了日の列に' KEEP(DENSE_RANK LAST ORDER BY X_END_DATE) 'を使いたいので、最新の終了日に対応する値を返します(https:// stackoverflow.com/a/121661/1509264) – MT0

関連する問題