我想选择一个数据库表的最新条目,该表包含具有相同产品编号(但日期不同)的多行。
在这种特殊情况下,我想用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
脚注
“选择*”仅是一种方便,上面仅用于缩写和/或因为细节未知。请完整指定选择子句。