2016-09-22 3 views
0

Я работал на этом упражнении на Codecademy в течение нескольких дней и до сих пор не мог понять, логика it.Below этом упражнение и код:SQL коррелирует подзапросы

Было бы интересно сделать заказ авиабилетов, давая им порядковый номер, основанный на времени, носителем. Например, если предположить, flight_id приращения с каждым дополнительным рейсом, мы могли бы использовать следующий запрос для просмотра полеты носителя, полетной идентификатор и порядковый номер:

SELECT carrier, id, 
     (SELECT COUNT(*) 
     FROM flights f 
     WHERE f.id < flights.id 
      AND f.carrier=flights.carrier) + 1 AS flight_sequence_number 
FROM flights; 

Я могу понять, что f виртуальная форма таблицы flights , но что делает f.id < flights.id? Означает ли это, что SQL сравнивает каждую строку в f с каждой строки в flights как

сравнить MQ 17107 с MQ 7869,

сравнить MQ 17107 с MQ 2205,

сравнить MQ 17107 с MQ 14979

......

сравнить MQ 7869 с MQ 2205,

сравнить MQ 7869 Wi й MQ 14979

......

Помимо, что же это на самом деле COUNT(*) рассчитывать? И почему +1?

Это результат изображения: query result

Любая помощь будет оценена. Благодарю.

+1

Подсчитайте количество полетов перед текущим идентификатором и добавьте 1. – jarlh

+1

Хорошая практика программирования имеет два разных псевдонима таблиц. Например. f1 и f2. – jarlh

+1

С помощью [modern SQL] (http://modern-sql.com/slides) это можно сделать намного проще с помощью простой оконной функции: 'row_number() over (порядок несущей несущей на основе id)' - нет необходимости в подзапрос. –

ответ

0

Запрос выбирает записи из табличных рейсов. Для каждой записи выбирается несущая, идентификатор и номер_последовательности_последовательности.

Итак, для каждой записи в полеты выполняется подзапрос. Он снова считывает столные полеты, но принимает только записи с одним и тем же носителем и идентификатором полета, меньшим, чем номер основной записи. Чтобы поговорить об основной записи запроса и записи суб-запроса, вам понадобится одна или две псевдонимы таблицы, так как в противном случае обе записи будут называться как полет, так и в полете. И не ясно, о каком из них вы говорите. Таким образом, таблица во внутреннем запросе получает псевдоним f. Теперь вы можете сравнить f.id < flights.id и f.carrier = flights.carrier.

COUNT (*) рассчитывает, следовательно, все записи ниже, чем идентификатор полета основной записи для его носителя, и, таким образом, номера строк оператора. Для наименьшего ID вы не найдете меньших идентификаторов, поэтому счетчик равен 0, и вы добавляете один из них, таким образом получая номер строки 1. Для второго наименьшего вы найдете одну запись с меньшим идентификатором, следовательно, вы получите счет 1, добавьте 1 и получите номер строки 2 и так далее.

Результаты будут выглядеть лучше, когда вы добавите заказ по предложению ORDER BY carrier, id, чтобы вы показывали результаты в используемом порядке.

Как уже упоминалось, некоторые современные СУБД предлагают аналитические функции, такие как ROW_NUMBER и запрос становится гораздо проще:

select 
    carrier, 
    id, 
    row_number() over (partition by carrier order by id) as flight_sequence_number 
from flights 
order by carrier, id; 
+0

Я все еще поглощаю ваши ответы. Но спасибо вам большое. – Eva

0

У вас есть список рейсов с flight_id, который говорит вам последовательность всех рейсов относительно друг друга.Какой запрос вы пытаетесь сделать, это получить последовательность каждого полета в отношении только рейсов одного и того же оператора. Например, если бы я спросил вас, что такое 50-й полет, было бы легко, так как вы могли просто искать рейс с flight_id = 50. Но если бы я спросил вас, что с 50-м рейсом US Airlines, у вас не было бы никакой идеи с таблицей, которую вы указали без какой-либо агрегации или использования разделов.

Давайте рассмотрим простой запрос выбора. Если вы выбрали бы все носители данного типа А, вы получите что-то вроде этого:

SELECT flight_id, carrier 
FROM flights 
WHERE carrier = A 

flight_id, carrier 
------------------ 
    4,  A 
    9,  A 
    10,  A 
    18,  A 
    20,  A 
    25,  A 
    26,  A 

Однако flight_id длиннее, порядковым номером нет, когда мы только глядя на несущей A. Бегство с идентификатором 4 ISN» 4-й полет наших результатов (который является полетом 18). Затем мы могли бы объединить данные, чтобы мы имели последовательность каждого полета относительно полетов той же самой несущей. Поэтому нам нужно подсчитать количество полетов одного типа перед каждой строкой, чтобы получить ее последовательность. В полете 4 нет более ранних полетов типа A, поэтому у него будет последовательность из 1 (0 полетов перед ним, мы добавим 1, чтобы начать последовательность в 1). Полет 9 имеет 1 полет перед ним, поэтому у нас есть последовательность 2 (1 полет до + 1 смещение = 2).

Мы должны сделать это для каждого полета в наших результатах, поэтому мы можем включить подзапрос в выбранную часть нашего запроса. Подзапрос в select будет похож на другой запрос на выбор, но позволит вам использовать данные во внешнем запросе и делает это для каждой строки, возвращаемой в результатах внешнего запроса.

Для того, что мы хотим сделать (найти порядковое число полетов в зависимости от их заказа и их носителя), подзапрос будет сравнивать каждый идентификатор строк со всеми строками в одной и той же таблице, если он меньше идентификатора текущей строки , это полет перед ним и будет в результатах подзапроса. COUNT агрегирует результаты этого подзапроса, так что это одно значение. Мы также гарантируем, что все результаты в нашем подзапросе совпадают с носителем текущей строки, на которую мы смотрим в нашем основном запросе. Мы должны использовать псевдоним для этого подзапроса, поскольку он выбирает из одной и той же таблицы и будет неоднозначным в противном случае, поэтому он использует псевдоним «f», чтобы отличить его от основного запроса. Мы также можем дать результаты этого подзапроса имя flight_sequence_number, которое хранится в новом столбце. Это позволит вам легко узнать последовательность всех полетов, а также последовательность полетов относительно одного и того же оператора.

+0

Спасибо за то, что вы так поняли. Это все разъясняет мне. – Eva