SQL-запрос работает только с одним столбцом и перестает работать, как только я добавляю второй столбец - PullRequest
0 голосов
/ 13 октября 2018

Я пытаюсь заставить этот запрос работать, но мне не удалось заставить его сделать это, вот что мне удалось сделать до сих пор:

select c.EID
from certified c
    inner join aircrafts a ON c.AID = a.AID
group by c.EID 
HAVING count(c.EID)  >= 3 and MAX(a.CRUISINGRANGE);

РЕЗУЛЬТАТЫ:

EID
'141582651'

'142519864'

'269734834'

'390487451'

'552455318'

'556784565'

'567354612'

'573284895'

Как видите, у меня есть внутреннее соединение со столом самолета, чтобы получить максимальную дальность полета, по сертифицированным данным я считаю и возвращаю пилотов, которые могут пилотировать более 3 самолетов.

Теперь моя проблема в том, что я не могу добавить a.AID к своему выбору, чтобы отобразить его, вот что я пробовал:

select c.EID, a.AID
from certified c
    inner join aircrafts a ON c.AID = a.AID
group by c.EID, a.AID
HAVING count(c.EID)  >= 3 and MAX(a.CRUISINGRANGE);

РЕЗУЛЬТАТЫ:

EID AID

0rows

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ:

EID          AID

'141582651'  '6475'

'142519864'  '8430'

'269734834'   '8430'

'390487451'   '7120'

'552455318'   '3383'

'556784565'   '7120'

'567354612'   '8430'

'573284895'   '7120'

но я получаю 0 строк при попытке сделать это.

DATA SAMPLE: 
Certified: 
EID        AID
142519864   1
269734834   1
550156548   1
567354612   1
11564812    2
141582651   2
142519864   2
242518965   2
269734834   2
552455318   2
556784565   2


AIRCRAFTS
AID    ANAME         CRUISING RANGE
1   Boeing 747-400  8430
2   Boeing 737-800  3383
3   Airbus A340-300 7120
4   British Aerospace Jetstream 41  1502
5   Embraer ERJ-145 1530
6   SAAB 340    2128
7   Piper Archer III    520
8   Tupolev 154 4103
9   Lockheed L1011  6900
10  Boeing 757-300  4010
11  Boeing 777-300  6441
12  Boeing 767-400ER    6475
13  Airbus A320 2605
14  Airbus A319 1805
15  Boeing 727  1504
16  Schwitzer 2-33  30
123 Airbus  1000
302 Boeing  5000
306 Jet01   5000
378 Airbus380   8000

1 Ответ

0 голосов
/ 13 октября 2018

Ваш вопрос действительно трудно понять;вы, кажется, на самом деле не заявили, что вы хотите в последовательной и последовательной манере.Из прочтения комментариев кажется, что вы хотели бы знать:

Самое дальнее, что может летать каждый пилот (который рассчитан на 3 или более самолетов).

Таким образом, вы ожидаете списокEID пилотов и максимальная дальность полета (из таблицы самолетов) по всем самолетам, которые пилот может летать.Пилот должен иметь возможность летать как минимум на 3 самолетах.

Шаги:

Составить список пилотов и расстояния, на которые может рассчитывать самолет, на который они рассчитаны:

SELECT c.EID, a.cruising_range
FROM certified c INNER JOIN aircrafts a ON c.AID = a.AID

Улучшение запроса для подсчета рейтингов и максимальной дальности полета на пилота (пилот может летать на самолете, у самолета есть дальность, поэтому, когда пилот летит на самолете, у пилота есть диапазон):

SELECT c.EID, COUNT(*) as count_ratings, MAX(a.cruising_range) max_range
FROM certified c INNER JOIN aircrafts a ON c.AID = a.AID
GROUP BY c.EID --per pilot

Улучшите запрос, чтобы выбрать только пилотов, которые могут летать как минимум на 3 самолетах:

SELECT c.EID, max_range FROM
(
  SELECT c.EID, COUNT(*) as count_ratings, MAX(a.cruising_range) max_range
  FROM certified c INNER JOIN aircrafts a ON c.AID = a.AID
  GROUP BY c.EID --per pilot
) pilot_ranges
WHERE
  pilot_ranges.count_ratings >= 3

Я мог бы использовать HAVING:

SELECT c.EID, MAX(a.cruising_range) max_range
FROM certified c INNER JOIN aircrafts a ON c.AID = a.AID
GROUP BY c.EID 
HAVING COUNT(*) >= 3

Но иногда есть преимуществов визуальном размещении запроса в виде набора шагов, а не попыток сделать все сразу, и использования подзапросов для мысленного формирования списка данных, а затем его изменения, фильтрации,добавить к этому .. все поэтапно.

Оптимизатор запросов, скорее всего, перезапишет эти запросы внутренне, чтобы они в конечном итоге выполнялись одинаково, так что выгода для человека в понимании и будущем обслуживании

Редактировать: вот запрос, который перечисляет EIDи AID для каждой комбинации пилот-самолет, где пилот способен летать на 3+ самолетах:

SELECT c.EID, a.AID FROM
(
  SELECT c.EID
  FROM certified c
  GROUP BY c.EID 
  HAVING count(*) >= 3
) find_pilots_can_fly_atleast_three
INNER JOIN certified c ON c.EID = find_pilots_can_fly_atleast_three.EID
INNER JOIN aircrafts a ON c.AID = a.AID

Сначала вы генерируете список интересных пилотов - это подзапрос find_pilots_can_fly_atleast_three, затем мы присоединяемсяэти данные обратно на сертифицированные и самолеты.В итоге мы получаем список пилотов, которые могут летать на 3 самолетах, и получаем подробную информацию о самолетах

Возможно, вы пытались сделать слишком много за один раз.Когда вы группируете, вы теряете определенные биты данных.При группировании пилотов, чтобы найти тех, кто может управлять самолетами 3+, мы ДОЛЖНЫ потерять идентификатор самолета и сохранить только идентификатор пилота.Если вы попытаетесь сохранить идентификационный номер самолета (потому что вы этого хотите), вы получите группы, у которых будет только 1, потому что каждая комбинация пилот-самолет уникальна.Таким образом, мы теряем идентификатор самолета в агрегацию (счет) и сохраняем идентификатор пилота.Это помогает нам узнать, сколько самолетов может летать каждый пилот.Чтобы выяснить , какие самолеты могут летать эти пилоты, мы ДОЛЖНЫ затем присоединить этот идентификатор пилота из запроса «найти 3+» обратно к списку самолетов-пилотов (сертифицированная таблица), чтобы развернуть его обратно в список.пилотов с самолетом

Всегда помните, что вам разрешено присоединять стол к себе, и это действительно важно в подобных случаях.Если у вас была таблица, полная адресов с датами, когда вы проживали по этому адресу, чтобы найти самый последний, у вас был бы запрос, получивший your_id, max(lived_there_until_date, но вы не можете сохранить другие данные об адресе - вы хотите, чтобыдата самой последней записи. А затем, если вы действительно хотите, чтобы оставшиеся данные из этой последней строки присоединялись к только что выполненному запросу, к таблице адресов, чтобы получить всю строку с самой последней датой alive_there_until

...