如何从 oracle sql 中只选择 1 行?
Posted
技术标签:
【中文标题】如何从 oracle sql 中只选择 1 行?【英文标题】:How to select only 1 row from oracle sql? 【发布时间】:2012-02-13 17:22:41 【问题描述】:我想使用 oracle 语法从表 DUAL
中仅选择 1 行。比如我要执行这个查询:
SELECT user
FROM DUAL
...它应该有 40 条记录。但我只需要一张唱片。 ...而且,我想在没有WHERE
子句的情况下实现它。
我需要 table_name 字段中的一些内容,例如:
SELECT FirstRow(user)
FROM DUAL
【问题讨论】:
什么版本的Oracle?使用 ROWNUM 或 ROW_NUMBER (9i+) 意味着需要 WHERE 子句 你给表命名了dual
吗?
@ypercube dual
是oracle中的系统表
@Ben,你真的不应该创建一个名为DUAL
的表。这有点像 C 语言中的 #define TRUE 0
- 当然,它可能对你有用,但未来的开发者会讨厌你。
你真的尝试过运行select user from dual
吗?如果没有,请尝试一下,看看你会得到什么。在标准的 oracle 系统上,您将获取正在执行命令的用户。
【参考方案1】:
如果你想只取回具有最少子查询的排序结果的第一行,试试这个:
select *
from ( select a.*
, row_number() over ( order by sysdate_col desc ) as row_num
from table_name a )
where row_num = 1;
【讨论】:
其中 sysdate_col 是您要排序的任何列的名称,当然,table_name 是您希望排序数据来自的表的名称。【参考方案2】:select a.user from (select user from users order by user) a where rownum = 1
会表现最好,另一种选择是:
select a.user
from (
select user,
row_number() over (order by user) user_rank,
row_number() over (partition by dept order by user) user_dept_rank
from users
) a
where a.user_rank = 1 or user_dept_rank = 2
在您需要不同子集的情况下,但我想您也可以使用 RANK()
但是,我也喜欢 row_number()
over(...)
,因为不需要分组。
【讨论】:
【参考方案3】:我们有 3 个选择来获取 Oracle DB 表中的第一行。
1) select * from table_name where rownum= 1
是最好的方法
2) select * from table_name where id = ( select min(id) from table_name)
3)
select * from
(select * from table_name order by id)
where rownum = 1
【讨论】:
感谢您的回答:根据第 3 点)“nowrum= 1”可能应该更改为“rownum = 1”。【参考方案4】:? 答案是:
你应该使用嵌套查询:
SELECT *
FROM ANY_TABLE_X
WHERE ANY_COLUMN_X = (SELECT MAX(ANY_COLUMN_X) FROM ANY_TABLE_X)
=> 在 PL/SQL 中,“ROWNUM = 1”不等于 TSQL 的“TOP 1”。
所以你不能使用这样的查询:“select * from any_table_x where rownum=1 order by any_column_x;”因为 oracle 获取第一行然后应用 order by 子句。
【讨论】:
请在您的回答中添加一些说明 应避免使用不寻常的语法,但没有充分的理由。在这种情况下,提供测试用例或错误编号会很有帮助。我隐约记得rownum = 1
的一些奇怪问题,但我们不应该再让旧的错误影响我们的代码。
@hgwhittle,Fuat 之所以正确是因为 ROWNUM 不关心“ordery by”,它只是抓取它可以找到的第一条记录并立即返回。所以换句话说,ROWNUM 限定符对“Order By”命令没有任何尊重。我希望不是这样,但 Fuat 是正确的,使用嵌套查询。【参考方案5】:
此语法在 Oracle 12c 中可用:
select * from some_table fetch first 1 row only;
select * from some_table fetch first 1 rows only;
select * from some_table fetch first 10 row only;
select * from some_table fetch first 10 rows only;
^^我只是想证明可以使用行或行(复数),而不管所需的行数是多少。)
【讨论】:
select * from some_table 仅获取前 1 行;它在我的 swl devloper 和 sql 中都不起作用,而且在 fetch 时出现错误。 你用的是oracle 12c吗? 我真的不知道,但是当我打开它时显示如下:SQL * PLus Release 10.1.0.4.2 is it not 12 c 正确 - 您使用的可能是 10.1.xxx 版本,您可以 SELECT * FROM V$VERSION【参考方案6】:select name, price
from (
select name, price,
row_number() over (order by price) r
from items
)
where r between 1 and 5;
【讨论】:
【参考方案7】:您使用 ROWNUM。
即。
SELECT user FROM Dual WHERE ROWNUM = 1
http://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns009.htm
【讨论】:
@ypercube 据我所知,确实如此。 (至少它适用于我安装的 oracle10g。) @bdares:它会起作用的,是的。但不是你的答案,order by
。
是的。 ROWNUM 是一个特殊的列,它被添加到枚举结果的结果集中。您也可以使用它来选择多个,例如,如果您想找到 10 名薪酬最高的员工,您可以说“SELECT user FROM Employees WHERE ROWNUM
@mkdess: 不,ORDER BY
在WHERE
之后应用。
你需要:SELECT * FROM (SELECT user FROM Employees ORDER BY SALARY DESC) WHERE ROWNUM <= 10
【参考方案8】:
我发现这个“解决方案”隐藏在其中一个 cmets 中。由于我查找了一段时间,我想强调一下(还不能评论或做这样的事情......),所以这就是我使用的:
SELECT * FROM (SELECT [Column] FROM [Table] ORDER BY [Date] DESC) WHERE ROWNUM = 1
这将从表中的最新条目中打印出我想要的 [Column] 条目,假设总是通过 SYSDATE 插入 [Date]。
【讨论】:
我发现如果您通过ROWID
订购它也可以使用,只要您从不删除任何记录并始终关心最后插入/修改的记录。
@vapcguy:不要期望 ROWID 是有序的,即使您从未从表中删除一行!即使它现在适用于您,也不能保证在未来的版本中也适用。
@D.Mika 实际上,如果它现在可以工作,并且您从不添加/删除/更新/删除记录,那么应该永远不会有任何问题。只有在您实际更改记录时才能更改记录。有一种误解认为ROWID
以某种方式被 Oracle 随机修改。它不是。它基于实际修改行,即删除一行,然后插入一行。插入的将获得旧的ROWID
。有一些东西,比如永远不会更新的静态表,美国的州就是一个很好的例子——如果它发生了变化,它可能会产生其他影响,无论如何,只要这没问题。
@vapcguy:嗯,这几乎是对的。但是还有其他操作会改变 ROWID。如果出于某种原因导出/导入表怎么办?还有其他操作,但其中一些需要启用行移动。我只想说,依赖未来可能会改变的实现细节并不是一个好主意。
@D.Mika 我确定是否有任何操作可以更改 ROWID
,如果有可能,一个好的 DBA 会查找它们并尽其所能避免它们正如我所描述的那样,它们正在影响这样一个静态表,只有应用程序应该在其上运行。可以使用SELECT
语句来代替表导出。导入会发生一次,然后再也不会发生。我明白你的意思,肯定需要小心,但问题远非不可避免。【参考方案9】:
比select max()
更灵活的是:
select distinct first_row(column_x) over (order by column_y,column_z,...) from Table_A
【讨论】:
【参考方案10】:据我所知,Oracle 中的dual
表是一个只有一行的特殊表。所以,这就足够了:
SELECT user
FROM dual
【讨论】:
那不是真的 select user from dual 应该给你所有的用户 Wikipediaa bout dual in Oracle也是如此 .. 刚刚在我的系统上试用过,作为 ypercube 和所有相关文档提及。 @本 @Ben dual 不是目录视图,它不会显示“所有用户”。为此,您可以使用 ALL_USERS 之类的视图。【参考方案11】:"FirstRow" 是一个限制,因此它位于where
子句中,而不是select
子句中。它被称为rownum
select * from dual where rownum = 1;
【讨论】:
请注意,与ORDER BY
结合使用时,这将无法按预期工作,因为排序仅发生在 where 子句之后。换句话说,要获得某个排序查询的顶部,rownum 完全没用。
@Nyerguds,这只是对了一半。您可以在 Where
之前使用 order by 进行查看查询。
什么,所以SELECT * FROM (SELECT * FROM ... WHERE ... ORDER BY ...) WHERE ROWNUM = 1
?好吧,这可能行得通,但它看起来很愚蠢,tbh。【参考方案12】:
如果有任何行可以,请尝试:
select max(user)
from table;
没有 where 子句。
【讨论】:
当然,您只需几秒钟就可以自己尝试一下【参考方案13】:Oracle中没有limit 1
条件(即mysql/PostgresSQL),需要指定where rownum = 1
。
【讨论】:
以上是关于如何从 oracle sql 中只选择 1 行?的主要内容,如果未能解决你的问题,请参考以下文章