首页 > 解决方案 > 大型记录集的复杂 SQL 查询

问题描述

我有 3 张桌子。让我们从解释第一个开始

tblDistance: (airport1, airport2, distance) // airport1 and airport 2 are airport codes

此表包含美国所有机场之间的距离(以英里为单位),总共有 3745 个机场,距离是使用嵌套 for 循环计算的,并且每次循环计数器都会递减。所以对于第一个机场,我们计算了 3744 个距离。对于第二个,我们计算了 3743 个距离,因为我们已经计算了它在第一个循环中与第一个机场的距离。现在假设第一个机场是Animas Air Park(K00C),第二个机场是Broadus Airport(K00F)。记录将在 tblDistance 中显示为

(KOOC, other3744aiports, distance)

第二机场

(K00C, K00F, distance) //This one record has been already calculated in 1st iteration of the loop
(KOOF, other3743aiports, distance)

因此,除了第一个机场之外,如果我们想查找特定机场的所有距离,可以说 K00F,我们需要下面给出的联合查询。

(SELECT * FROM tblDistances WHERE tblDistances.airport1 = 'K00F')
UNION ALL 
(SELECT * FROM tblDistances WHERE  tblDistances.airport2 = 'K00F');

我希望我已经解释清楚了。现在让我们来看看另外两张桌子。它们被称为tblHavetblNeed

tblHave: (departure, departCode, arrival, arrivalCode, flightDate)
tblNeed: (departure, departCode, arrival, arrivalCode, flightDate)

Departure 是航班起飞的机场名称,departCode(K00C, K00F)是机场代码,同样适用于到达和到达代码。

假设我们在 tblNeed 中有从(出发)旧金山国际机场(KSFO)到(到达)南本德 Rgnl(KSBN)的航班。现在真正的问题来了,我们必须找到tblHave中的所有航班

  1. 在与给定航班相同的日期和
  2. 出发机场是(KSFO)或在旧金山国际机场 (KSFO) 500 英里范围内,使用上述联合(我们称之为 qryDepart)和
  3. 到达机场是(KSBN)或在South Bend Rgnl (KSBN) 500 英里范围内,使用上述联合(我们称之为 qryArrival)

示例 qryArrival

SELECT tblDistances.airport2 as nearBy
FROM tblDistances
WHERE  tblDistances.airport1 = 'KSFO' AND (((Abs([tblDistances].[distance]))<=500)) 
UNION ALL SELECT tblDistances.airport1 as nearBy
FROM tblDistances
WHERE  tblDistances.airport2 = 'KSFO' AND (((Abs([tblDistances].[distance]))<=500));

我不知道我怎么能找到这个,而且所有机场的距离组合总数超过 700 万。记录在 Access 数据库中。我的图是我从 tblDistances 找到附近的出发机场和附近的到达机场,然后使用 IN 子句找到最终结果

Select * from tblHave where arrivalCode IN (qryArrival) AND departCode IN (qryDepart) AND Date = #dd/mm/yyyy#;

这是行不通的,并且由于记录的数量非常大,工会花费了太多时间。

标签: sqlms-access

解决方案


你不需要在UNION这里使用。您可以在一个查询中执行此操作,至少可以将执行时间减少一半,因为您不会检查每条记录两次。您可以使用嵌套iif语句来确定要使用哪个字段nearBy,然后更改您WHERE以检查记录的两个字段。像这样:

SELECT 
    iif(
        tblDistances.airport = 'KSFO',
        tblDistances.airport2,
            iif(tblDistances.airport2 = 'KSFO',
                tblDistances.airport1,
                null)
        ) as nearBy
FROM tblDistances
WHERE  
    (
        tblDistances.airport1 = 'KSFO'
        OR tblDistances.airport2 = 'KSFO'
    )
    AND (((Abs([tblDistances].[distance]))<=500)) 

如果您使用语句会更容易阅读CASE,但 Access 不支持CASE. 上面的查询与以下内容相同:

SELECT 
    CASE 
        WHEN tblDistances.airport1 = 'KSFO' then tblDistances.airport2 
        WHEN tblDistances.airport2 = 'KSFO' then tblDistances.airport1
    END as nearBy
FROM tblDistances
WHERE  
    (
        tblDistances.airport1 = 'KSFO'
        OR tblDistances.airport2 = 'KSFO'
    )
    AND (((Abs([tblDistances].[distance]))<=500)) 

推荐阅读