顺便说一句,我不经常使用ORACLE PL/SQL,但我需要了解,如果在我之前由公司中的其他人创建的这个函数中有任何错误,因为它没有返回我被告知的最新记录。我在其他一些论坛中发现,他们建议使用最大值(DateColumn)而不是"row_numer = 1“,但不太确定如何以及在哪里合并。
--知道--我们使用Oracle版本12,CustomObjectTypeA是一些不再在这里的老员工定义的自定义Oracle对象类型,V_OtherView是由一些不再在这里的老员工定义的Table_Mnd类型,V_ABC_123是由一些不再在这里的老员工创建的视图。
CREATE OR REPLACE FUNCTION F_TABLE_APPROVED (NUMBER_F_UPD number, NUMBER_F_GET VARcHAR2)
RETURN Table_Mnd
IS
V_OtherView Table_Mnd
BEGIN
SELECT CustomObjectTypeA (FromT.NUMBER_F,
FromT.OP_CODE,
FromT.CATG_CODE,
FromT.CATG_NAME,
FromT.CATG_SORT,
FromT.ORG_CODE,
FromT.ORG_NAME
FromT.DATA_ENTRY_VALID,
FromT.NUMBER_RECEIVED,
FromT.YEAR_1,
FromT.YEAR_2)
BULK COLLECT INTO V_OtherView
FROM (SELECT NUMBER_F,
OP_CODE,
CATG_CODE,
CATG_NAME,
CATG_SORT,
ORG_CODE,
ORG_NAME
DATA_ENTRY_VALID,
NUMBER_RECEIVED,
YEAR_1,
YEAR_2,
ROW_NUMBER() OVER (PARTITION BY BY ORG_CODE ORDER BY NUMBER_RECEIVED DESC, LOAD_DATE DESC) AS ROW_NUMBER
FROM V_ABC_123
WHERE NUMBER_F = NUMBER_F_UPD AND DATA_ENTRY_VALID <> 'OnGoing'
AND LOAD_DATE >= (SELECT sysdate-10 FROM dual)
AND LOAD_DATE <= (SELECT DISTINCT LOAD_DATE
FROM V_ABC_123
WHERE NUMBER_RECEIVED = NUMBER_F_GET)) FromT
WHERE FromT.ROW_NUMBER=1;
RETURN V_OtherView;
END F_TABLE_APPROVED;发布于 2018-01-23 13:27:36
查询的重要部分包括:
SELECT ...
FROM (select ...,
ROW_NUMBER()
OVER (PARTITION BY ORG_CODE
ORDER BY NUMBER_RECEIVED DESC,
LOAD_DATE DESC) AS ROW_NUMBER
...) FromT
WHERE FromT.ROW_NUMBER = 1;"ROW_NUMBER“列根据下面的window子句计算:
PARTITION BY ORG_CODE
ORDER BY NUMBER_RECEIVED DESC, LOAD_DATE DESC这意味着对于每个ORG_CODE,它将按NUMBER_RECEVED,LOAD_DATE降序对所有记录进行排序。请注意,如果列是Oracle DATE,则它们将仅精确到最近的秒;因此,如果有多个记录的日期/时间在完全相同的1秒间隔内,则不能保证此排序顺序是唯一的。因此,ROW_NUMBER的逻辑将任意选择其中之一(即,恰好最先发出的记录),并将其赋值为"1",这将被视为“最新的”。相同SQL的后续执行(理论上)可能会返回不同的记录。
可疑的部分是NUMBER_RECEIVED,它听起来像是一个数字,而不是日期?按此排序意味着具有最高NUMBER_RECEIVED的记录将是首选记录。这是故意的吗?
我不确定为什么PARTITION在那里,这会导致查询为它找到的每个ORG_CODE值返回一条“最新”记录。我只能假设这是故意的。
问题在于,查询只能根据提供给它的数据来确定“最新记录”。在这种情况下,数据可能不够细粒度,无法确定哪条记录是实际的“最新”记录。
https://stackoverflow.com/questions/48393646
复制相似问题