我有以下查询,如果编辑日期不为空,则需要返回最近的记录,并且应该随机化,否则记录应该随机化。我尝试了下面的顺序,但是我得到了丢失的关键字错误。
{{1}}
答案 0 :(得分:1)
如果我告诉你,你试图获得每个ID的记录,其中包含最高日期(如果存在更多具有相同日期的记录,则为随机的)或具有NULL日期(当更多NULL记录与存在相同的ID。
假设这个数据
ID EDIT_DATE TEXT
---------- ------------------- ----
1 01.01.2015 00:00:00 A
1 01.01.2016 00:00:00 B
1 01.01.2016 00:00:00 C
2 01.01.2015 00:00:00 D
2 01.01.2016 00:00:00 E
2 F
2 G
对于ID = 1,您需要B或C,对于ID = 2,您需要F或G。
此查询执行此操作。 使用的功能是使用NULLS FIRST 进行排序,添加随机值作为最后一个排序列 - 如果所有前面的列都相同,则获得随机结果。
with dta as (
select 1 id, to_date('01012015','ddmmyyyy') edit_date, 'A' text from dual union all
select 1 id, to_date('01012016','ddmmyyyy') edit_date, 'B' text from dual union all
select 1 id, to_date('01012016','ddmmyyyy') edit_date, 'C' text from dual union all
select 2 id, to_date('01012015','ddmmyyyy') edit_date, 'D' text from dual union all
select 2 id, to_date('01012016','ddmmyyyy') edit_date, 'E' text from dual union all
select 2 id, NULL edit_date, 'F' text from dual union all
select 2 id, NULL edit_date, 'G' text from dual),
dta2 as (
select ID, EDIT_DATE, TEXT,
row_number() over (partition by ID order by edit_date DESC NULLS first, DBMS_RANDOM.VALUE) as rn
from dta)
select *
from dta2 where rn = 1
order by id
;
ID EDIT_DATE TEXT RN
---------- ------------------- ---- ----------
1 01.01.2016 00:00:00 B 1
2 F 1
希望你能重新使用这个想法,如果你需要一些不同的结果......
答案 1 :(得分:0)
声明WHERE
始终在声明ORDER BY
之前应用。因此,在您的查询中,首先应用WHERE ROWNUM = 1
并且仅在此之后将应用order by case
...用于单个记录。
也许您需要添加另一个子查询,首先执行ORDER BY
,以正确的顺序获取行集,然后执行WHERE ROWNUM = 1
以选择单行。
法规ORDER BY ... DBMS_RANDOM.VALUE, c.edit_date
看起来很奇怪。事实上,记录集将按DBMS_RANDOM.VALUE
排序,如果行集有几行等于DBMS_RANDOM.VALUE
,我们还会按c.edit_date
对它们进行排序。