web-dev-qa-db-ja.com

3つのテーブルを結合し、最大日時の異なる値のみを返す

私はこれを2週間ずっとやってみましたが、役に立たないようです。ここに含まれる3つのテーブル。しかし、結果が異なるケースであると期待しています。同じ日付とユーザーに対して。それ以外の場合は、すべてを返す必要があります。

SELECT DISTINCT A.CASENO,A.DATE,A.TIME,A.TRANNO,B.PCODE,C.PDESC,A.USER
FROM tableA A
RIGHT JOIN tableB B ON A.CASENO=B.CASENO
RIGHT JOIN tableC C ON C.PCODE=B.PCODE
WHERE A.DATE between 140124 and 140331

同じ時間とトランノではないため、結果はまだ重複しています。 CASENOの結果を参照してください。= 08088040

A.CASENO   A.DATE   A.TIME   A.TRANNO   B.PCODE   C.PDESC    A.USER
08088040   140124   182516   321         TYQ      PREPLAN1   ANTHONY
08088040   140124   182131   318         TYQ      PREPLAN1   ANTHONY
36360569   140128   111056   431         CVB      POSTT1     MARIA
36360569   140310   113221   433         CVB      POSTT1     MARIA
37386911   140213   150240   230         M2P      PLANAVG    FELISE
37386911   140213   135220   223         M2P      PLANAVG    HECTOR
39222881   140128    94122   104         TYQ      PREPLAN1   ELLA
40895213   140213   164409   104         CVB      POSTT1     WINNIE
51311866   140124   103203   319         M2P      PLANAVG    BRATT

同じ日付、同じユーザー、同じpcodeおよびpdesc、caseno。時間とトランノの違いにより、08088040が2回出てきました。ここで、max trannoは、同じケースnoで行われた最新のトランザクションを示します。最大時間は、その特定のケース番号に対して行われた最新の日時アクションも示しています。 2014年1月24日@ 18:25:16。同じ日付とユーザーの場合、最新の取引の詳細が必要です。

以下のスクリプトを最初の条件として追加しようとしましたが、結果は0でした。また、出力を取得する前に長い遅延を引き起こしています。

WHERE A.TRANNO=(SELECT MAX(TRANNO) FROM tableA A where A.CASENO=B.CASENO)

参考までに、残りはケース番号。 37386911はユーザーが異なるため一意であると見なされるため、返してほしい。一方、ケース番号36360569も日付が異なるため一意のレコードです。同じユーザーですが。

それで、どうすればこれを達成できますか?私が見つけた例の多くは、個別の値を取得するための1つのテーブルと1つの基準についてのみ示していました。

スクリプトは、SQL DB2で使用されるものでなければなりません。私は実際にはSQLの背景はまったくありません。以前に行ったクエリのほとんどは試行錯誤に基づいていましたが、このような複雑な条件がないため、成功しました。

うまくいけば、ここの誰かの専門家が知識を共有することができます。

2
DeLL

これは典型的な「グループあたりの最大のN」問題であり、通常はウィンドウ関数を使用して解決されます。

select caseno, date, time, tranno, pcode, pdesc, user
from (
  select a.caseno,a.date,a.time,a.tranno,b.pcode,c.pdesc,a.user,
         row_number() over (partition by a.caseno order by a.tranno desc) as rn
  from tablea a
    right join tableb b on a.caseno=b.caseno
    right join tablec c on c.pcode=b.pcode
  where a.date between 140124 and 140331
) t
where rn = 1;

難読化されたタイムスタンプ情報を使用して、並べ替えを行うこともできます。

row_number() over (partition by a.caseno order by a.date desc, a.time desc) as rn

あなたの例を考えると、おそらく違いはありません。

仮定:

  • ケースの最大トランノを持つレコードには、最大日付/時刻もあります
  • Trannoとcasenoの組み合わせはユニークです

次のクエリを使用できます。

SELECT a.caseno
     , a.date
     , a.time
     , a.tranno
     , b.pcode
     , c.pdesc
     , a.user
FROM ( SELECT aa.caseno
            , MAX(aa.tranno) AS tranno
       FROM tablea aa
       WHERE aa.date BETWEEN 140124 AND 140331
       GROUP BY aa.caseno
     ) maxa
JOIN tablea a ON maxa.caseno = a.caseno AND maxa.tranno = a.tranno
JOIN tableb b ON a.caseno = b.caseno
JOIN tableC C ON c.pcode = b.pcode
0
SQB