相同的查询给出不同的结果

时间:2017-12-14 17:09:15

标签: sql database pgadmin

因此,对于在学校的作业,我们必须从数据库中提取计数。问题如下,

- 19)包含“欧洲”的时区名称中的多少个机场被用作具有唤醒“M”或“L”的航线的源机场(source_airport_id)

这是我提出的代码,

SELECT count(DISTINCT airports.id) FROM airports WHERE timezone_name LIKE '%Europe%' AND id IN
(SELECT source_airport_id FROM routes WHERE id IN 
(SELECT id FROM route_aircrafts WHERE aircraft_id IN 
(SELECT id FROM aircrafts WHERE wake_size IN ('M', 'L'))));
它返回544,而教授回答566。

SELECT count (DISTINCT airports.id)
FROM airports, routes, route_aircrafts, aircrafts

WHERE airports.id = routes.source_airport_id
AND routes.id = route_aircrafts.route_id
AND aircrafts.id = route_aircrafts.aircraft_id

AND airports.timezone_name LIKE'%Europe%'
AND aircrafts.wake_size IN ('M', 'L'); --566

对我来说,这两个人应该做同样的事情,我无法理解为什么答案是不同的。

2 个答案:

答案 0 :(得分:0)

要在查询中获得相同的答案,您需要:

SELECT count(DISTINCT airports.id) FROM airports WHERE timezone_name LIKE '%Europe%' AND id IN
(SELECT source_airport_id FROM routes WHERE id IN 
(SELECT route_id FROM route_aircrafts WHERE aircraft_id IN 
(SELECT id FROM aircrafts WHERE wake_size IN ('M', 'L'))));

您使用的是主ID字段而不是外键route_id。您得到了大致相似的结果,因为值必须存在显着重叠。

答案 1 :(得分:0)

我会选择以下内容:

SELECT COUNT(DISTINCT airports.id)
FROM airports 
INNER JOIN routes ON airports.id = routes.source_airport_id
INNER JOIN route_aircrafts ON routes.id = route_aircrafts.route_id
INNER JOIN aircrafts ON route_aircrafts.aircraft_id = aircrafts.id
    AND aircrafts.wake_size IN ('M', 'L')
WHERE airports.timezone_name LIKE '%Europe%'

说明:

SELECT COUNT(DISTINCT airports.id)

您不希望多次计算重复airports.id次。

FROM airports 

这是您所依据的主要表格。所有其他表都是从这一个构建的。

INNER JOIN routes ON airports.id = routes.source_airport_id

INNER JOIN仅包含两个表中匹配的行。匹配airports.idroutes.source_airport_id

INNER JOIN route_aircrafts ON routes.id = route_aircrafts.route_id

INNER JOIN仅包含两个表中匹配的行。匹配routes.idroute_aircrafts.route_id

INNER JOIN aircrafts ON route_aircrafts.aircraft_id = aircrafts.id
AND aircrafts.wake_size IN ('M', 'L')

与上面的INNER JOIN相同。我们为wakes添加了一个额外的过滤器。对于INNER JOIN,此过滤器也可以在WHERE子句中执行,而不会更改结果。将过滤器放在JOIN中可以将意图保持在一起(并且优化器可能会以这种方式过滤)。对于OUTER JOINJOIN中的WHERE vs过滤过滤可能会返回不同的结果(取决于您的数据)。

WHERE airports.timezone_name LIKE '%Europe%'

现在我们从timezone_name的基表中的airports过滤整个结果集。

使用SQL时,在 SETS 中考虑您的数据非常重要。这将帮助您编写更高性能,更少编程的查询。