现在我有一个非常简单的SQL: 从表A中选择*
我知道结果将按“rowid”排序(我不太确定,我是新生)。 如果没有“order by”,Oracle将无法保证SQL结果的顺序。
这是我的问题:
一旦我按照这样的顺序得到了结果:...... A ...... B ....
现在我想按照这个顺序得到结果:...... B ...... A ....
在A没问题之前做B。 怎么做?
注意1:这是一个实验。请耐心思考我的问题。
注意2:不要更改任何记录的主键,也不要使用任何DDL,并使用相同的SQL“select * from table A”。
通知3:
create table A(id NUMBER(20) primary key, name VARCHAR2(30));
insert into A values(1,'one');
insert into A values(2,'two');
select * from A;
我尝试过:更新,插入,删除一些无效的记录。
答案 0 :(得分:5)
修改
鉴于此要求:
不要更改SQL
select * from table A
。
更改表格A以更改结果顺序
答案是明确的:这是不可能。
(保留我的初步答案作为参考)
“我知道结果将按rowid
排序” - 不,它们 不 。
行将以数据库认为最有效的任何顺序返回。
没有,绝对不能保证以任何特定顺序返回行,除非指定ORDER BY
。
仅 获取特定订单的方式 以使用ORDER BY
。
如果您希望'B'
出现在'A'
之前,那么只需按降序排列:
select *
from table_A
order by some_col DESC
您可以通过应用表达式或函数将更多逻辑放入ORDER BY
运算符。如果你是想要按照字母顺序列出顶部的'B'
和其他所有内容,您可以执行以下操作:
select *
from table_a
order by
case
when some_col = 'B' then 0
else 1
end,
some_col
答案 1 :(得分:1)
您一直试图“澄清”您的问题。我最好能理解,你试图提出某种“益智游戏”。但是你的益智游戏是荒谬的。我认为您缺少的是理解“为什么”按照您插入行的顺序返回行。当您了解这一点时,您将更好地了解您的问题实际上在询问什么,以及为什么您无法解决它。
如果你 1)创建一个标准的Oracle表“A”,其中包含PK ID和一个(或多个)其他列和
2)只插入几行(例如,数据少于填充数据块的数据),
3)不进行后续索引,移动,重新排序,压缩等
然后是的,Oracle的所有现有实现都将通过以插入它们的相同顺序返回两行来解析SELECT * FROM A.
这是因为 1)当前的Oracle实现将按照接收顺序将新记录写入空数据块,并且
2)后续SELECT * FROM A,如果没有提供更好计划的索引,将导致全表扫描。由于您的所有数据都在一个数据块中,并且当前的Oracle实现按顺序读取块中的数据,因此“SELECT * FROM A”将“稳定地”按照您插入的顺序返回行。
在这种情况下,你的益智游戏似乎是:一个人可以对表A发出INSERT / UPDATE / DELETE语句,这样当前的Oracle实现将执行“SELECT * FROM TABLE A”并以相反的顺序返回你的两行。这样的挑战通过例如删除你的两行并重新插入ID = 2行然后ID = 1行秒来解决这个问题(并且实际上只是)。但是您的声明“不要更改任何记录的主键”表示删除/重新插入不是一个选项。在这种情况下,是的,即使从一个令人费解的角度来看,你也要求不可能的事情:你面临的挑战是在Oracle上挥动魔杖,以便它从头到尾开始读取同一数据文件中的行。
ETA:你也不允许使用DDL;否则,你可以这样做一个有趣的黑客来获得预期的效果:
create table A(id NUMBER(5) primary key, name VARCHAR2(10))
partition by list (id)
(partition p1 values (2),
partition p2 values (1));
insert into A values(1,'one');
insert into A values(2,'two');
select * from a;
ID NAME
---- ---------
2 two
1 one
答案 2 :(得分:0)
只有 订购 是为了工作。但是你可以通过一个简单的函数来实现所需的安排,你想要的逻辑就是返回行的格式并使用该函数。