SQL-запрос с условием подсчета - PullRequest
0 голосов
/ 28 ноября 2018

Вот моя структура таблицы:

CREATE TABLE CITY(
  CITY_ID NUMBER(3) CONSTRAINT CITY_ID_PK PRIMARY KEY,
  CITY_NAME VARCHAR2(20) CONSTRAINT CITY_NAME_NN NOT NULL);

CREATE TABLE PILOT(
  PILOT_ID NUMBER(3) CONSTRAINT PILOT_ID_PK PRIMARY KEY,
  LAST_NAME VARCHAR2(20) CONSTRAINT LAST_NAME_NN NOT NULL,
  FIRST_NAME VARCHAR2(20) CONSTRAINT FIRST_NAME_NN NOT NULL,
  CITY_ID NUMBER(3) CONSTRAINT CITY_ID_FK REFERENCES CITY(CITY_ID),
  SALARY NUMBER(7,2) CONSTRAINT SALARY_CK CHECK (SALARY >= 5000 AND SALARY <= 7000));

CREATE TABLE PLANE(
  PLA_ID NUMBER(2) CONSTRAINT PLANE_ID_PK PRIMARY KEY,
  PLA_DESC VARCHAR2(20) CONSTRAINT PLANE_DESC_NN NOT NULL,
  MAX_PASSENGER NUMBER(3),
  CITY_ID NUMBER(3) CONSTRAINT PLANE_CITY_ID_FK REFERENCES CITY(CITY_ID),
  CONSTRAINT MAX_PASSENGER_CK CHECK (MAX_PASSENGER <= 500));

CREATE TABLE FLIGHT(
  FLIGHT_ID NUMBER(3) CONSTRAINT FLIGHT_ID_PK PRIMARY KEY,
  PILOT_ID NUMBER(3) CONSTRAINT FLIGHT_PILOT_ID_FK REFERENCES PILOT(PILOT_ID),
  PLA_ID NUMBER(2) CONSTRAINT FLIGHT_PLA_ID_FK REFERENCES PLANE(PLA_ID),
  CITY_DEP NUMBER(3) CONSTRAINT FLIGHT_CITY_DEP_FK REFERENCES CITY(CITY_ID),
  CITY_ARR NUMBER(3) CONSTRAINT FLIGHT_CITY_ARR_FK REFERENCES CITY(CITY_ID),
  DEP_DATE DATE,
  DEP_TIME NUMBER(4),
  ARR_TIME NUMBER(4),
  CONSTRAINT ARR_TIME_CK CHECK (ARR_TIME > DEP_TIME));

Вопрос, который я ставлю в этой лаборатории, состоит в том, чтобы отображать пилотов (ID и имя), которые выполняют два или более полета из Монреаля (Требуется, чтобы я использовал название города в запросе, а не ID)

Вот что я придумал до сих пор:

SELECT PILOT_ID, LAST_NAME, FIRST_NAME
FROM PILOT
JOIN FLIGHT USING (PILOT_ID)
WHERE CITY_DEP=(SELECT CITY_ID
                FROM CITY
                WHERE CITY_NAME='MONTREAL')

Очевидно, что это дает мне частьответ, но он не отображает именно ту информацию, которая мне нужна, это просто пилоты, которые делают этот бой> = 2 раза.

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Отредактировано с новой информацией о структуре данных

Понимание вашей цели

Я полагаю, что понимаю вашу цель - запросить данные пилотного уровня для пилотов, которые вылетели из Монреаляпо крайней мере, дважды за один день.

Решение для запроса

Если мои предположения верны, я считаю, что вы можете удовлетворить свои потребности, выполнив что-то похожее на это:

CREATE GLOBAL TEMPORARY TABLE flight_per_day ON COMMIT PRESERVE ROWS AS
SELECT
       p.pilot_id,
       f.dep_date,
       COUNT(CASE WHEN c.city_name = 'MONTREAL' THEN 1 ELSE NULL END) as 
        montreal_cnt
  FROM flights f
       LEFT JOIN pilot p ON p.pilot_id = f.pilot_id
       LEFT JOIN city c on f.city_dep = c.city_id
 GROUP BY 1, 2;


    SELECT
           p.pilot_id,
           p.first_name,
           p.last_name
      FROM flight_per_day fp
           LEFT JOIN pilot p ON p.pilot_id = fp.pilot_id
     WHERE fp.montreal_cnt>=2

или без временной таблицы, которую вы могли бысделать

SELECT
       p.pilot_id,
       p.first_name,
       p.last_name
  FROM
       (SELECT
              p.pilot_id,
              f.dep_date,
              -- Find the total number of flights (COUNT) where (CASE WHEN) a flight departs from Montreal (THEN) count it otherwise (ELSE) ignore it (NULL)
              COUNT(CASE WHEN c.city_name = 'MONTREAL' THEN 1 ELSE NULL END) as 
                montreal_cnt
         FROM flights f
              -- Join in pilot table to get the counts by pilot_id
              LEFT JOIN pilot p ON p.pilot_id = f.pilot_id
              -- Join in city table to get city_name instead of city_id
              LEFT JOIN city c on f.city_dep = c.city_id
        GROUP BY 1, 2) fp
       LEFT JOIN pilot p ON p.pilot_id = fp.pilot_id
-- Only give me the data for pilots who have flown out of Montreal at least twice in one day
 WHERE fp.montreal_cnt>=2
0 голосов
/ 28 ноября 2018

Для каждого пилота вам нужно подсчитать, сколько рейсов у этого пилота из Монреаля, а затем получить пилотов, у которых есть 2 или более рейсов.Это работа для GROUP BY и HAVING.

SELECT PILOT_ID, LAST_NAME, FIRST_NAME
FROM PILOT
JOIN FLIGHT USING (PILOT_ID)
JOIN CITY ON (CITY_DEP = CITY_ID)
WHERE CITY_NAME='MONTREAL'
GROUP BY PILOT_ID, LAST_NAME, FIRST_NAME
HAVING COUNT(*) >= 2;
0 голосов
/ 28 ноября 2018

Вы можете использовать FETCH ROWS

SELECT PILOT_ID, LAST_NAME, FIRST_NAME
FROM PILOT
JOIN FLIGHT USING (PILOT_ID)
WHERE CITY_DEP=(SELECT CITY_ID
                FROM CITY
                WHERE CITY_NAME='MONTREAL')
FETCH FIRST 2 ROWS ONLY
...