2017-09-12 4 views
0

ユーザーが複数のレコードを送信したテーブルがあります。各レコードには、レコードが完全に完了したかどうかを示すCOMPLETEというフィールドがあります。SQL COMPLETEフィールドが0の場合にのみ、最新のレコードを検索します。

COMPLETEが0、LOCATION、DATEが同じで、COMPLETEが1の場合は追加レコードが存在しないユーザーの最新レコードを取得する方法が必要です。各レコードに、タイプ、金額、合計など。USER、LOCATION、およびDATEは同じでも、これらは異なる場合があります。

提出日と自動増分ID番号を示すSUB_DATEフィールドとIDフィールドがあります。こちらの表は、次のとおりです。SUB_DATEは後でそれが同じ名前、場所、および日付の情報を持っており、何COMPLETEがないというID 3であるため、

ID NAME LOCATION DATE  COMPLETE SUB_DATE TYPE1 AMOUNT1 TYPE2 AMOUNT2 TOTAL 
1 user1 loc1 2017-09-15 1  2017-09-10 Food 12.25 Hotel 65.54 77.79 
2 user1 loc1 2017-09-15 0  2017-09-11 Food 12.25 NULL  0 12.25 
3 user1 loc2 2017-08-13 0  2017-09-05 Flight 140  Food  5 145.00 
4 user1 loc2 2017-08-13 0  2017-09-10 Flight 140  NULL  0 140 
5 user1 loc3 2017-07-14 0  2017-07-15 Taxi 25  NULL  0 25 
6 user1 loc3 2017-08-25 1  2017-08-26 Food 45  NULL  0 45 

私が望む結果を取得することであるが、ID 4です値は1です。

それは、最新のユーザーのための記録、場所、日付、およびコンプリートは0

ですので、私はまた、あなたが私を助けるためにあなたの答えを説明することができれば、私はそれをも感謝し、ID 5を取得したいと思いますソリューションで何が起きているのかを理解する。私は完全に理解したが、しようとした場合

+2

サンプルデータ、希望の結果、およびタグを使用しているデータベースに提供してください。データと結果は* text *でなければならず、問題のイメージではありません。 –

+0

私はこれを一歩一歩踏み出すことを勧めます。最も新しいレコードを見つけることから始めます。 –

+0

場所と日付は何と同じですか? – SEarle1986

答えて

0

わからないこの

SELECT * 
FROM (
      SELECT *, 
        MAX(CONVERT(INT,COMPLETE)) OVER (PARTITION BY NAME,LOCATION,DATE) AS CompleteForNameLocationAndDate, 
        MAX(SUB_DATE) OVER (PARTITION BY NAME, LOCATION, DATE) AS LastSubDate 
      FROM your_table t 
     ) a 
WHERE CompleteForNameLocationAndDate = 0 AND 
     SUB_DATE = LastSubDate 

だから我々はここでやっていること:

まず、あなたはManagement Studioでちょうど内側のクエリを実行した場合、あなたはそれが何をするかが表示されます:

最初のmax関数は、テーブル内のデータをそれぞれ固有の名前、場所、日付で区切ります。 データの場合、ID 1 & 2が最初のパーティション、3 & 4が2番目のパーティション、5が3番目のパーティション、6が4番目のパーティションです。 これらのパーティションごとに、完全な列に最大値が表示されます。したがって、最大値の1を持つパーティションはすべて完了しています。

変換機能にも注意してください。これは、COMPLETEがBIT(1または0)のデータ型であり、max関数がそのデータ型で機能しないためです。したがって私たちはINTに変換します。 COMPLETE列がINT型の場合は、変換を取り出すことができます。再び一意の名前、場所、日付ごとに

秒MAX関数パーティションが、我々はmax_sub日に私たちの名前の最新のレコードの日付を与えるこの時間を得ている、場所、日付

だから我々はそれを取りますそれを派生テーブルに追加します。 SQL ServerではクエリのWHERE句でウィンドウ関数を使用できないため、これを行う必要があります。ウィンドウ関数は、私たちが行ったようにOVERキーワードを利用するものです。理想的な世界では、SQLは私たちに任せます

SELECT *, 
     MAX(CONVERT(INT,COMPLETE)) OVER (PARTITION BY NAME,LOCATION,DATE) AS CompleteForNameLocationAndDate, 
     MAX(SUB_DATE) OVER (PARTITION BY NAME, LOCATION, DATE) AS LastSubDate 
FROM your)table t 
WHERE MAX(CONVERT(INT,COMPLETE)) OVER (PARTITION BY NAME,LOCATION,DATE) = 0 AND 
     SUB_DATE = MAX(SUB_DATE) OVER (PARTITION BY NAME, LOCATION, DATE) 

しかし、派生テーブルを使用する必要があります。

それでは、私たちは基本的に記録が完了としてマークされていない名前、場所、日付・パーティションです

CompleteForNameLocationAndDate = 0 

たちの派生テーブルからすべてを選択します。

その後、我々は、各パーティション

SUB_DATE = LastSubDate 

理にかなっている希望、ないあなたが必要とする詳細レベル確認のための唯一の最新の記録を求め、さらにフィルタリング?

tblBooking 
BookingID 
PersonID 
LocationID 
Date 
Complete 
SubDate 

tblPerson 
PersonID 
PersonName 

tblLocation 
LocationID 
LocationName 

tblType 
TypeID 
TypeName 

tblBookingType 
BookingTypeID 
BookingID 
TypeID 
Amount 
(あなたの例では、テーブルを想定すると、予約と呼ばれている):

側として、私は次のように(もちろん、あなたは、より良い、この問題を説明するために簡略化していない限り)あなたのテーブルを再構築になり

予約情報にType3またはType4を追加する場合は、テーブルレイアウトを変更する必要はありません

+0

ありがとうございます。これはうまくいくようです。私はSQLに少し慣れていますが、あなたは教育目的のために何をしたのか説明できますか? –

+0

心配しないで、私は答えを更新します... – SEarle1986

+0

また、私はあなたが望むか – SEarle1986

関連する問題