2016-11-11 5 views
1

は私が照会していた表である:集計後にSELECTクエリに列を追加するにはどうしたらいいですか?ここ

EmployeeId, Salary, Date 
8, 500, 2016-11-02 
8, 500, 2016-09-21 
8, 500, 2016-10-18 
9, 500, 2016-10-18 
9, 500, 2016-09-21 
9, 500, 2016-11-02 
10, 1000, 2016-11-02 
10, 700, 2016-09-21 

私が従業員とどのような彼らの給与は、その特定の従業員のために利用できる最新の日付にあったのリストを選択します。サンプルデータの場合、これは同じ日付(11-02)ですが、必ずしもそうであるとは限りません。マイクエリ:

戻っている
SELECT EmployeeId, Salary, MAX(Date) 
FROM table 
GROUP BY EmployeeId. Salary 
ORDER BY EmployeeId 

8, 500, 2016-11-02 
9, 500, 2016-11-02 
10, 700, 2016-09-21 
10, 1000, 2016-11-02 

私の予想される出力は次のとおりです。

8, 500, 2016-11-02 
9, 500, 2016-11-02 
10, 1000, 2016-11-02 

私は給料なしで集約した場合、私は期待どおりの結果を得るが、私が必要給料を見ることができる。ポスト集約を含める方法はありますか?

+2

クエリを別名でサブクエリにします。これは他のテーブルに結合できる派生テーブルです。 –

+0

あなたの期待する出力を表示してください – TheGameiswar

+0

@ダンブルクック私はあなたに詳細な詳細に行くように頼むことができますか? – Scott

答えて

3

(すべてのRDBMSバージョンでサポートされているわけではないため)ウィンドウ機能の前に、インライン表示でこれを実行します。

まず、あなたのニーズを考慮:

  • あなたは従業員の最大の日付と従業員のIDで構成されたデータセットを必要としています。
  • あなたが最初に達成するために...

を使用すると、グループ化することによって得ることができなかったテーブルオフ生データを必要とする、我々は(以下別名「B」)インライン・ビューを生成しません。 次に、必要な追加情報を取得するためにベースセットに戻ってきます。内部結合が望ましくないレコードを排除することを可能にする。外部クエリでグループの必要性を完全に否定します。

SELECT A.EmployeeId, A.Salary, A.Date 
FROM table A 
INNER JOIN (SELECT max(date) mDate, EmployeeID 
      FROM table 
      GROUP BY EmployeeID) B 
    on A.EmployeeID = B.EmployeeID 
and A.Date = B.MDate 
ORDER BY EmployeeId 

RDBMSとワーキングセットの観点でデータを考えるとどのようにそれらのセットを濾過することができ、所望の結果を達成するために一緒に戻って接合されています。ほとんどの(すべてではない)RDBMSアクティビティーでのセットに基づく処理が最も効率的です。ウィンドウ関数(別名分析関数)の導入により、サブクエリなしでセットの世代を行うことができます。それらをデータ分析の強力な機能にします。最初は頭を悩ませています。

どうすればいいですか:ROW_NUMBER() OVER (PARTITION BY EmployeeId ORDER BY Date DESC) RNは正確に何ですか?

新しく発生した各従業員(パーティション)に対して1から始まる行番号を降順で割り当てます(したがって、各従業員の最新の日付は常に1です!)ただし、SQLの操作順序によって選択値LASTが生成されるため(where句がすでに実行されているため)、1はwhere句のクエリで使用できません。これは、ウィンドウ関数を目的の結果にしてRN = 1で制限し、サブクエリでラップしてからRN = 1にアクセスし、最新の日付の従業員のレコードのみを返すことを意味します。 RDBMSは、分析機能とは独立してテーブルの生成を実行することができるので、RDBMSを同時に処理し、非常に迅速に応答を提供することができる。

1

あなたは最後の値を参照すること)(窓関数ROW_NUMBERを使用することができます

Select * 
From ( 
     Select *,RN = Row_Number() over (Partition By EmployeeId Order by Date Desc) 
     From YourTable 
    ) A 
Where RN=1 
2

最新のを選び出すためにウィンドウ関数を使用することができます。

with cte as (
    select EmployeeId, 
     Salary, 
     Date 
     ROW_NUMBER() OVER (PARTITION BY EmployeeId ORDER BY Date DESC) RN 
    from [table] 
) 
select EmployeeId, 
    Salary, 
    Date 
from cte 
where RN = 1 

場合にはその明確ではありません、 EmployeeIdによって基本的に「パーティショニング」され、各パーティション内の行に降順で番号が付けられ、次にこの番号が1の行(つまり各従業員の最新)が選択されます。

1

私はこれらの操作をAPPLYで行う傾向があります。

SELECT t1.EmployeeId, t2.Salary, t2.Date 
FROM table t1 
CROSS APPLY (SELECT TOP 1 Salary, Date 
      FROM table 
      WHERE EmployeeId = t1.EmployeeId 
      ORDER BY Date DESC) t2 
ORDER BY t1.EmployeeId 
+1

非常に十分に活用されていないアプローチ。私は、この節のインラインビューとウィンドウの機能のパフォーマンスを理解するのに時間を費やす必要があります。 – xQbert

+0

@xQbertええ、私は実際にはさまざまなソリューションのパフォーマンスの違いについてはコメントできません。自分自身と私の同僚は、これが最も読みやすいと思うだけです。 –

関連する問題