为什么选择单个属性返回的行少于选择Oracle SQL中的所有列的行

伊森51

创建的表和进行的查询不是此问题的主要重点,令我困惑的是,为什么第一个查询和第二个查询返回不同的行数

drop table Reserves;
drop table Sailors;
drop table Boats;

create table Sailors (
    sid      char(1) not null,
    sname    char(1) not null,
    rating   int,
    age      int not null,
    primary key (sid)
);

create table Boats (
    bid      char(1) not null,
    bname    char(1) not null,
    color    varchar(5),
    primary key (bid)
);

create table Reserves (
    sid      char(1) not null,
    bid      char(1) not null,
    rdate    int not null,
    primary key (sid, bid, rdate),
    foreign key (sid) references Sailors(sid)
        on delete cascade,
    foreign key (bid) references Boats(bid)
        on delete cascade
);


------------------------------------------------------------------------------

-- Insert values

insert into Sailors values ('1', 'q', 90, 24);
insert into Sailors values ('0', 's', 60, 22);
insert into Sailors values ('2', 'd', 80, 20);
insert into Sailors values ('3', 'w', 70, 18);
insert into Sailors values ('4', 'a', 60, 19);
insert into Sailors values ('5', 'l', 80, 17);
insert into Sailors values ('6', 'o', 90, 18);
insert into Sailors values ('7', 'q', 70, 20);
insert into Sailors values ('8', 'd', 60, 16);
insert into Sailors values ('9', 'i', 80, 22);

insert into Boats values ('0', 'U', 'red');
insert into Boats values ('1', 'P', 'red');
insert into Boats values ('2', 'Q', 'blue');
insert into Boats values ('3', 'C', 'green');
insert into Boats values ('4', 'L', 'blue');
insert into Boats values ('5', 'O', 'blue');
insert into Boats values ('6', 'A', 'red');
insert into Boats values ('7', 'C', 'red');
insert into Boats values ('8', 'Y', 'green');
insert into Boats values ('9', 'N', 'blue');

insert into Reserves values ('0', '0', 3);
insert into Reserves values ('0', '1', 2);
insert into Reserves values ('0', '2', 1);
insert into Reserves values ('0', '2', 3);
insert into Reserves values ('1', '0', 4);
insert into Reserves values ('3', '2', 2);
insert into Reserves values ('4', '0', 3);
insert into Reserves values ('4', '0', 1);
insert into Reserves values ('4', '1', 3);
insert into Reserves values ('4', '6', 4);
insert into Reserves values ('4', '7', 1);
insert into Reserves values ('5', '8', 2);
insert into Reserves values ('5', '9', 2);
insert into Reserves values ('7', '4', 4);
insert into Reserves values ('7', '5', 1);
insert into Reserves values ('8', '3', 2);
insert into Reserves values ('9', '3', 3);
insert into Reserves values ('9', '0', 1);
insert into Reserves values ('9', '6', 1);
insert into Reserves values ('9', '8', 2);

commit;


select *
from Sailors join Boats on color='red' natural left outer join Reserves
where rdate is null;

select sid
from Sailors join Boats on color='red' natural left outer join Reserves
where rdate is null;

我想找到尚未订购所有红船的水手的sid,上面的第一个查询返回我期望的正确行,尽管如此,第二个查询仅返回sid = 2和sid = 6的行,尽管有两个查询都是一样的 sid 2和6的水手是唯一没有预订任何船只的水手。

数学家

据我所知,这似乎是Oracle实施中的一个错误natural [...] join我将做一些测试,看看它是否也影响内部联接。

代替natural联接,可以使用语法left|right|inner join USING(...)并在using子句中提供列名称的​​列表列的列表应该是在连接的两个成员中具有相同名称所有的列表

对您提供的数据进行的非常简单的实验(即使using(sid, bid)仅对其中的+1),结果与我们在第一个查询中编写的结果相同,但仅using(sid)在第二个查询中相同如果任一查询-不管什么选择,无论是*sid-您使用using的语法,你得到的输出或者您的第一个或第二个查询中相同的行数,这取决于什么你把在using条款。

因此,Oracle对第二个查询所做的事情是完全错误的。我只能推测,但是我相信Oracle首先查看该SELECT子句,也许还查看其他子句,以查看它需要从每个表中检索哪些(例如,这告诉优化器它可以使用哪些索引,等等。)然后,在此步骤中,Oracle在第二个查询中确定它不需要bid然后,当将“自然”联接转换为自己的内部代码时,它不会bid作为联接列抛出哪个是错误的-这就是为什么我将此称为“错误”。

重要说明:其他人评论说,这两个查询都是“错误的”,因为它们不能解决您要解决的问题。这可能是完全正确的。我什至没有看你的问题说明;在这里,我正在回答您的问题,无论出现什么问题,该问题都是有效的-这就是为什么两个查询会产生不同数量的行。即使在您的用例中它们是“错误的”,他们也应该从本质上给出“相同”的错误答案,而不是“不同”的错误答案。那是我上面讨论的唯一内容。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在 Oracle SQL 中,如何使选择返回 ID 在列表中的所有行?

行到sql中的列(不是所有行)

为什么sql函数返回所有计数和单个选择返回正确值?

SQL选择一列中具有重复值的所有行

SQL Server选择所有列中具有1值的行

SQL:选择在特定列中具有特定值的帐户的所有行

汇总SQL中列不同的所有行?

Java SQL从列中获取所有行

SQL Server将所有行选择具有重复列名的单个列

选择不重复的行,其中列中的所有值均是同一SQL Server

SQL使用减号函数消除特定列中的行,但从表中返回所有列

如何从表中的所有列中选择所有重复行的所有出现?

选择列尚未返回现有结果的所有行

SQL选择单行“历史”中的所有行

选择列表中的Pandas DataFrame列值的所有行

熊猫 | 选择组中的所有行和特定列

sql-选择所有具有多个相同列的所有行

Oracle SQL-如果多列中的一列不为null,则提取所有行

如何选择表中不存在的列并为所有返回的行返回NULL结果

SQL 选择链接表中所有行在 x 列中具有相同值的行

选择所有行作为纯Oracle SQL中的一个表类型对象

如何连接sql中的所有行

Scala Spark:汇总所有行中的所有列

对列中的所有行对执行操作

SQL Server:从同一列中具有匹配值的第一行之后的列中选择所有行

使用SQL选择列1中具有相同值但列2和3中具有不同值的所有行

SQL选择求和/平均所有行

选择列Jquery下的所有行

Notepad ++-从列中选择所有行