【问题标题】:Do this with a single SQL使用单个 SQL 执行此操作
【发布时间】:2008-10-02 06:29:39
【问题描述】:

我有一张这样的桌子:

行按 CLNDR_DATE DESC 排序。

我需要找到与突出显示的行对应的 CLNDR_DATE,换句话说:
查找 EFFECTIVE_DATE IS NOT NULL 的最顶层行组, 并返回该组最后一行的 CLNR_DATE。

通常我会打开一个游标并从上到下循环,直到在 EFFECTIVE_DATE 中找到一个 NULL。那我就知道我要找的日期是CLNDR_DATE,是在上一步得到的。

但是,我想知道是否可以使用单个 SQL 来实现相同的目标?

【问题讨论】:

  • 您所问的似乎并不算太​​糟糕,但是您能否澄清一下-您是说您需要它来获取有效日期中最后一个空值之后的表中最早的记录吗?

标签: sql oracle


【解决方案1】:

警告:无论如何都不是 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 在最后一个没有之后。

如果您希望 first withfirst without 之后,请将子查询更改为使用 min() 而不是 max()。

【讨论】:

    【解决方案2】:

    使用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 (order by clndr_date desc) 返回前一个 clndr_date,如果这是第一行,则使用 null。

    (编辑:固定顺序)

    【讨论】:

    • over(按 clndr_date DESC 排序)完成了这项工作。但是,是的,太慢了:-(
    • 这样做的好处是它会显示所有的差距,而不仅仅是最新的,这可能是也可能不是 OP 想要的,很可能不是从外观上看。
    【解决方案3】:

    此记录集中的第一个结果就是您要查找的结果。根据您的数据库,您可能只能通过使用 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
    

    【讨论】:

      【解决方案4】:

      当您在 Oracle 环境中时,您可以使用分析函数 (http://www.orafaq.com/node/55),这是非常强大的工具来执行您所要求的查询。

      使用标准 SQL 我认为这是不可能的,但也许一些 SQL 专家会提出一些不错的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-13
        • 1970-01-01
        • 1970-01-01
        • 2021-04-01
        • 2012-12-25
        • 2023-03-09
        相关资源
        最近更新 更多