当我运行下面的脚本时,即使使用distinct
,我也会一直收到重复的结果。
select distinct
a.SDT, a.fNo, b.IDType, b.pNo, b.pfName, b.plName, b.PDoB, b.Street, b.City, c.Phone
from Scheduled_Flight a, Passenger b, pass_Phone c
where fNo = '0000021'
and
a.SDT = '08-sep-2017 17:30';
答案 0 :(得分:2)
"即使使用不同的"
,我仍然会收到重复的结果
您的结果集中没有重复项。相反,你有一个笛卡尔产品,它是一个航班,三个乘客和三个电话号码的组合。该集合中的每条记录都是唯一的,因此distinct
没有任何影响。
问题是您的from
子句中没有连接条件。 passenger
上的列应该是flight
上的外键,pass_phone
上的列是passenger
上的外键。
很容易修复:你只需要加入表格。假设您的数据模型一致,您的查询应如下所示(并且您不需要DISTINCT):
select a.SDT, a.fNo, b.IDType, b.pNo, b.pfName, b.plName, b.PDoB, b.Street, b.City,c.Phone
from Scheduled_Flight a
join Passenger b on b.fNo = a.fNo
join pass_Phone c on c.pNo = b.bNo
where a.fNo = '0000021'
and a.SDT = '08-sep-2017 17:30';
但是,我注意到在您的查询版本中,您没有加fNo
前缀。这让我觉得你在passenger
上没有该名称的列(否则查询将在ORA-00918: column ambiguously defined
上失败)。因此,外键列的命名方式不同,或者您还没有得到它们。
"是否可以只指定没有时间的日期?"
是的。使用ANSI date literal例如date '2017-09-08'
"是否可以只指定日期而没有时间仍能从数据库中产生结果?"
这取决于数据的存储方式。 Oracle日期与时间元素一起存储。如果未指定时间(或截断时间元素),则time元素默认为午夜。这通常会捕获初学者,例如因为伪列sysdate返回当前日期和时间,而不仅仅是当前日期。
因此,如果您知道日期存储在没有时间元素的表中,您可以这样做:
where a.sdt = date '2017-09-08'
但如果你不知道,你可以截断......
where trunc(a.sdt) = date '2017-09-08'
或测试范围
where a.sdt >= date '2017-09-08'
and a.sdt < date '2017-09-09'
&#34;以下代码如何仍然产生重复结果?
select distinct r.sNo, r.tCode, s.fNo, s.SDT
from Airplane r, Scheduled_Flight s
where SDT >= SYSDATE -1;
飞机属性不能具有s.SDT属性。&#34;
没有看到输出我无法确定,但我敢打赌,这个查询也不会产生重复记录。您所拥有的产品是将所有AIRPLANE记录与所有与sdt
过滤器匹配的FLIGHT记录组合在一起的产品。
这是另一个数据建模问题。当然,飞机没有飞行时间:一架飞机进行多次飞行。但是将飞机分配到飞机上是完全合理的。事实上,确保你没有飞机比飞机飞行更多的飞机至关重要,而且这架飞机并不打算从伦敦起飞前往马德里。计划在中途前往香港。
你真的应该使用ANSI 92语法,正如我在你之前发布的代码的答案中所示。显式连接不仅使查询更容易理解,而且可以防止这样的错误。事实上,您显然没有任何候选列可以立即加入,这突出了数据模型中的缺陷。
select distinct r.sNo, r.tCode, s.fNo, s.SDT
from Airplane r
INNER JOIN Scheduled_Flight s ON ????
where SDT >= SYSDATE -1;
答案 1 :(得分:1)
我没有看到任何重复的行,如果你比较每一行的每一行,每一行都是唯一标识的,因为你正在做笛卡尔积,你得到多条记录。但是每一行都是彼此独特的。