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. 我们在工作中的一张表上有一个类似的设置(每个“事物”有多个“行”,但你只处理“最新”的一个),我运行了一个子选择类型查询和一个JOIN通过 Visual 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按该列的降序排列不为空的行,按 分区ID_NUM。主 SELECT 然后简单地检索排名为 的行1

于 2012-08-08T17:47:48.673 回答