使用单个SQL执行此操作
时间:2020-03-06 15:00:44 来源:igfitidea点击:
我有一个看起来像这样的表:
这些行按CLNDR_DATE DESC排序。
我需要找到与突出显示的行相对应的CLNDR_DATE,换句话说:
找到最上面的一组行,其中EFFECTIVE_DATE不为空,
并返回该组最后一行的CLNR_DATE。
通常,我将打开一个游标并从上到下循环,直到在EFFECTIVE_DATE中找到NULL。然后,我知道我要查找的日期是在上一步中获得的CLNDR_DATE。
但是,我想知道是否可以通过单个SQL达到相同的效果?
解决方案
警告:绝不是DBA。 ;)
但是,这是一个未经测试的快速刺探:
SELECT min(CLNDR_DATE) FROM [TABLE] WHERE (EFFECTIVE_DATE IS NOT NULL) AND (CLNDR_DATE > ( SELECT max(CLNDR_DATE) FROM [TABLE] WHERE EFFECTIVE_DATE IS NULL ))
假设我们要第一个CLNDR_DATE加上EFFECTIVE_DATE,最后一个不带。
如果我们想要第一个with之后的第一个with,则将子查询更改为使用min()而不是max()。
该记录集的第一个结果就是我们要寻找的。根据数据库,我们可能只能使用LIMIT或者TOP返回此行。
SELECT CLNDR_DATE FROM TABLE WHERE CLNDR_DATE > (SELECT MAX(CLNDR_DATE) FROM TABLE WHERE EFFECTIVE_DATE IS NOT NULL) ORDER BY CLNDR_DATE
当我们在Oracle环境中时,可以使用分析功能(http://www.orafaq.com/node/55),这些功能非常强大,可以执行我们所要求的查询。
我认为使用标准SQL是不可能的,但是也许某些SQL专家会提出一些不错的解决方案。
使用Oracle的分析功能(未经测试)
select * from ( select clndr_date, effective_date, lag(clndr_date, 1, null) over (order by clndr_date desc) prev_clndr_date from table ) where effective_date is null
lag(clndr_date,1,null)over(按clndr_date desc排序)
返回前一个clndr_date,如果这是第一行,则使用null。
(编辑:固定顺序)