Сложный SQL-запрос для большого набора записей - PullRequest
0 голосов
/ 29 сентября 2018

у меня 3 таблицы.Давайте начнем с объяснения первого

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

Эта таблица содержит расстояния в милях между всеми аэропортами Америки. Всего 3745 аэропортов, и расстояния были рассчитаны с использованием вложенного цикла for, а для каждого циклаСчетчик был уменьшен.Итак, для 1-го аэропорта мы рассчитали 3744 расстояния.Для второго мы вычислили 3743 расстояния, так как мы уже рассчитали его расстояние в первом цикле с первым аэропортом.Теперь предположим, что первый аэропорт был Анимас Эйр Парк (K00C) , а второй аэропорт Аэропорт Бродус (K00F) .Записи будут отображаться в tblDistance как

(KOOC, other3744aiports, distance)

Для второго аэропорта

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

Так, за исключением 1-го аэропорта, если мы хотим найти все расстояния для конкретного аэропорта, скажем, K00F мынужен запрос на объединение, приведенный ниже.

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

Я надеюсь, что объяснил это ясно.Теперь давайте перейдем к другим 2 таблицам.Они называются tblHave и tblNeed

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

Вылет - это название аэропорта, из которого вылетит рейс, и код вылета (K00C, K00F) - это код аэропорта и то же самое относится к коду прилета и прилета.

Предположим, что у нас есть рейс из (вылета) Международный аэропорт Сан-Франциско (KSFO) до (прилета) Саут-Бенд Ргнл (KSBN) в Табл.Теперь возникает реальная проблема: мы должны найти все рейсы в tblHave , которые

  1. В тот же день, что и данный рейс, и
  2. Аэропорт вылета (KSFO) или в пределах 500 миль от Международный аэропорт Сан-Франциско (KSFO) с использованием объединения, как указано выше (назовем его qryDepart) И
  3. Аэропорт прилета (KSBN) или в пределах 500 миль от South Bend Rgnl (KSBN) с использованием объединения, как указано выше (назовем его 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));

Я не могу понять, как я могу найти это, а также общее количество дистанционных командировок для всех аэропортов составляет более 7 миллионов.Записи находятся в базе данных Access.Я имею в виду, что из tblDistances я нахожу ближайшие аэропорты вылета и ближайшие аэропорты прибытия, а затем использую предложение IN, чтобы найти окончательные результаты

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

, это не работает, и объединение занимает слишком много времени, так какнет записей очень большой.

1 Ответ

0 голосов
/ 29 сентября 2018

Вам не нужно использовать 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)) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...