2

この副選択を回避する方法はありますか?私はこのクエリを可能な限り効率的にしようとしています。そうすることで、副選択を避けようとしています。

ID_NUMによってテーブル上で最後に置き換えられた行を探しています。

副選択は、最後に置き換えられた行のみを戻すように配置されています。これはそれを行うための最良の方法ですか?

クエリは私が望むように完全に機能するので、最後の小さな副選択まで無視してかまいません。

SELECT   
  A.ID_NUM,
  A.DOB,
  A.NAME,
  A.REPLACED_TMESTMP  
FROM MYTABLE A, MYTABLE B  
WHERE   
  A.ID_NUM = B.ID_NUM
  AND A.REPLACED_TMESTMP IS NOT NULL
  AND B.REPLACED_TMESTMP IS NULL
  AND A.DOB <> B.DOB
  several other conditions...

  AND A.REPLACED_TMESTMP  
    = (SELECT MAX(C.REPLACED_TMESTMP)  
      FROM MYTABLE C  
      WHERE C.ID_NUM = A.ID_NUM  
      AND A.REPLACED_TMESTMP IS NOT NULL  
      )
; 

これが私が何をする必要があるかを理解するのに役立ついくつかの擬似コードです

Select all from table
where a duplicate ID number exists
    that has an active row (no replaced time stamp)
    and has an inactive row(s)
    only bring back the most current replaced row for each ID num.
4

3 に答える 3

2

副選択をとして書き直すことができますJOIN。ここで動作しているテーブルの1つに同様の設定があり(「もの」ごとに複数の「行」がありますが、「最新の」もののみを処理します)、サブ選択タイプのクエリを実行し、JOINVisual Explainを介したタイプであり、見積もりによると、JOIN処理にかかるCPU秒はかなり短くなります(もちろん、これは単なる見積もりであり、テーブルは私のものとは大きく異なる可能性があります。塩)。

クエリを少し変更しました。これには、探しているすべての情報が含まれているはずです。

SELECT INACTIVE.ID_NUM
      ,INACTIVE.DOB
      ,INACTIVE.NAME,
      ,INACTIVE.REPLACED_TMESTMP  
FROM (
    SELECT *
    FROM MYTABLE
    WHERE REPLACED_TMESTMP IS NULL
) AS ACTIVE
JOIN (
    SELECT *
    FROM MYTABLE
    WHERE REPLACED_TMESTMP IS NOT NULL
) AS INACTIVE
  ON ACTIVE.ID_NUM = INACTIVE.ID_NUM
 AND ACTIVE.DOB   <> INACTIVE.DOB
  -- several other conditions...

JOIN (
    SELECT ID_NUM,
           MAX(REPLACED_TMESTMP) AS TIMESTAMP
    FROM MYTABLE
    GROUP BY ID_NUM
) MAX_REPLACE
  ON INACTIVE.ID_NUM           = MAX_REPLACE.ID_NUM
 AND INACTIVE.REPLACED_TMESTMP = MAX_REPLACE.TIMESTAMP
于 2012-08-08T21:10:05.070 に答える
1
SELECT   
  A.ID_NUM,  
  MAX(A.REPLACED_TMESTMP) AS MOST_RECENT_REPLACED_ROW
FROM MYTABLE A,
     MYTABLE B
WHERE   
    A.ID_NUM = B.ID_NUM
    AND A.REPLACED_TMESTMP IS NOT NULL
    AND B.REPLACED_TMESTMP IS NULL
GROUP BY A.ID_NUM
;
于 2012-08-08T17:06:22.993 に答える
1

ご使用のバージョンのDB2がこのROW_NUMBER()機能をサポートしている場合は、次のようにすることができます。

WITH ranked AS (
  SELECT
    ROW_NUMBER() OVER (
      PARTITION BY replaced.ID_NUM
      ORDER BY replaced.REPLACED_TMESTMP DESC
    ) AS rnk.
    replaced.ID_NUM,
    replaced.REPLACED_TMESTMP,
    replaced.... /* other columns as necessary */
  FROM MYTABLE replaced
    INNER JOIN MYTABLE active ON replaced.ID_NUM = active.ID_NUM
  WHERE replaced.REPLACED_TMESTMP IS NOT NULL
    AND active.REPLACED_TMESTMP IS NULL
    AND ... /* your other conditions */
)
SELECT
  ID_NUM,
  REPLACED_TMESTMP,
  ...
FROM ranked
WHERE rnk = 1
;

このROW_NUMBER()関数REPLACED_TMESTMPは、nullでない行に、その列の降順で、で分割して番号を割り当てますID_NUM。次に、メインのSELECTは、としてランク付けされた行を取得するだけ1です。

于 2012-08-08T17:47:48.673 に答える