我想选择一个数据库表的最新条目,该表包含具有相同产品编号(但日期不同)的多行。
在这种特殊情况下,我想用TKP_NOISE_MOTOR_RESULTS过滤PRODUCT_NUMBER表,该SAVEDATE在表中至少出现5次,并且要从该子集中检索每行中最新的行。 prdocut号

我设法创建了这样一个查询,但是有三个子查询T1,T2,T3。我有感觉,只需两个表就可以完成,不需要内部联接。但是创建它花费了很多时间,因为很难将脚本从MySQL转换为Oracle。

是否可以优化以下查询,以减少子查询的需要?

SELECT * FROM
messfeld.TKP_NOISE_MOTOR_RESULTS T1
JOIN
(
  SELECT PRODUCT_NUMBER, COUNT(*)
  FROM messfeld.TKP_NOISE_MOTOR_RESULTS
  GROUP BY PRODUCT_NUMBER
  HAVING COUNT(*)>5
) T2
ON T1.PRODUCT_NUMBER=T2.PRODUCT_NUMBER
WHERE T1.SAVEDATE BETWEEN '27-AUG-14' AND '28-AUG-14' AND
(T1.SAVEDATE, T1.PRODUCT_NUMBER) IN
(
SELECT MAX(T3.SAVEDATE), T3.PRODUCT_NUMBER
FROM messfeld.TKP_NOISE_MOTOR_RESULTS T3
WHERE
T2.PRODUCT_NUMBER=T3.PRODUCT_NUMBER
GROUP BY PRODUCT_NUMBER
);

最佳答案

除非使用的是较旧的Oracle版本,否则可以使用COUNT()ROW_NUMBER()的解析形式来得出所需的结果,我相信。试试这个:

SELECT
      *
FROM (
      SELECT
            TNMR.*
          , COUNT(*) OVER (PARTITION BY TNMR.PRODUCT_NUMBER) AS CN
          , ROW_NUMBER() OVER (PARTITION BY TNMR.PRODUCT_NUMBER
                               ORDER BY TNMR.SAVEDATE DESC) AS RN
      FROM messfeld.TKP_NOISE_MOTOR_RESULTS TNMR
      ) T1
WHERE T1.CN >= 5 AND T1.RN = 1
AND T1.SAVEDATE BETWEEN '27-AUG-14' AND '28-AUG-14'
;


但是,我确实不建议将dd-mmm-yy作为日期文字,并且我从不使用BETWEEN作为日期范围,而是使用以下内容:

AND T1.SAVEDATE >= to_date('27-08-2014','dd-mmm-yyyy')
AND T1.SAVEDATE < to_date('28-08-2014','dd-mmm-yyyy') + 1 -- 1 day added




脚注
“选择*”仅是一种方便,上面仅用于缩写和/或因为细节未知。请完整指定选择子句。

07-24 09:38
查看更多