【问题标题】:SELECT 4 latest rows from Oracle table with join从带有连接的 Oracle 表中选择 4 个最新行
【发布时间】:2015-04-01 10:30:43
【问题描述】:

我对 Oracle 很陌生,所以我对 ROWNUM 语句并不完全熟悉。我正在尝试从我的表中获取最新的 4 篇文章。我得到了 4 个结果,但它们是 2012 年的文章,即使我的日期排序设置为 DESC。任何帮助都会很棒。

Oracle 查询:

SELECT bt.article_id, ba.* 
FROM articles_types bt 
LEFT JOIN blog_articles ba 
ON ba.article_id = bt.article_id 
WHERE ROWNUM < 5 
ORDER BY Published DESC

【问题讨论】:

  • 在传统的Oracle SQL语句中,引用Rownum的Where子句先被解析,然后才解析Order By,导致结果错误。这是一个看起来不错的语法示例,如果更多人会解析它,它会被正确解析,但是计算机首先执行所有 Where 子句,忽略实际上依赖于输出本身的伪列函数(因为 Order By 更改输出)。您还必须知道,任何没有 Order By 的语句根本没有任何逻辑排序。

标签: sql oracle date join rownum


【解决方案1】:

只是一个疯狂的猜测,但在 rownum 限制之前排序结果:

select t.* from
(
SELECT * 
FROM articles_types bt 
LEFT JOIN blog_articles ba 
ON ba.article_id = bt.article_id 
ORDER BY Published DESC
) T
WHERE ROWNUM <= 4 

这行得通,问题是列名重复

【讨论】:

  • 抱歉应该提到我已经尝试过了,但我只是在 oracle 开发人员中收到以下错误:ORA-00918: column ambiguously defined 00918. 00000 - "column ambiguously defined" *Cause: *Action: Error在行:1 列:8
  • @huddds - 你从两个表中都得到了article_id;您应该从ba 指定您想要的列,而不是使用*(这通常是一个好主意),并省略重复项。
  • 谢谢,我会记下这一点,我还在学习 oracle
【解决方案2】:

where 子句在 order by 子句之前计算。所以这里发生的情况是,您选择了数据库返回的前四行(完全任意顺序),然​​后按Published 的降序对它们进行排序。

一种解决方案是将where 子句移至外部查询:

SELECT *
FROM   (SELECT    bt.article_id, ba.* 
        FROM      articles_types bt 
        LEFT JOIN blog_articles ba ON ba.article_id = bt.article_id 
        ORDER BY Published DESC)
WHERE  ROWNUM < 5

替代方案,在 Oracle 12c 中,您可以(终于!)使用 fetch first 子句:

SELECT      bt.article_id, ba.* 
FROM        articles_types bt 
LEFT JOIN   blog_articles ba ON ba.article_id = bt.article_id 
ORDER BY    Published DESC
FETCH FIRST 4 ROWS ONLY

【讨论】:

  • FETCH FIRST 很方便!
【解决方案3】:

rownum 函数在 order by 之前应用,因此它会选择它找到的前 4 个无序记录。

要使用rownum 获得您正在寻找的结果,您必须基本上将此查询转换为子查询,并在外部查询中应用rownum

SELECT *
FROM
(SELECT 
    bt.article_id, ba.* 
FROM 
    articles_types bt 
LEFT JOIN 
    blog_articles ba 
ON 
    ba.article_id = bt.article_id 
ORDER BY 
    Published DESC)
WHERE rownum < 5

【讨论】:

  • 我试过这个并得到以下错误:ORA-00918:列模糊定义 00918。00000 -“列模糊定义”*原因:*操作:行错误:1 列:8
  • 您的两个表似乎都有一个名为“article_id”的列,并且您将它们都与子查询一起拉入,因此存在歧义。您可以列出您想要的 ba 表中的所有列(减去 article_id),或者只是不选择子查询中的 bt.article_id 列
猜你喜欢
  • 2011-03-22
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
  • 2021-06-26
  • 1970-01-01
  • 2019-02-23
相关资源
最近更新 更多