Принять максимальное коррелированное значение в Oracle? - PullRequest
2 голосов
/ 04 апреля 2020

У меня есть следующие таблицы в моей базе данных Oracle 11g:

CREATE TABLE travels
(
Day DATE,
Flight_Code VARCHAR2(7),
Airplane_Code VARCHAR2(7),
CONSTRAINT pk PRIMARY KEY(day,flight_code)
);

и

CREATE TABLE boardings
(
Passport VARCHAR2(7),
Day DATE,
Flight_Code VARCHAR2(7),
Luggage_Weight NUMBER(4,2),
CONSTRAINT pk PRIMARY KEY(passport,day,flight_code)
);

Поэтому я пытаюсь сделать запрос, чтобы увидеть для каждого самолета это был рейс (Day и Flight_Code), в котором он перевозил максимальный вес, причем это количество всегда превышает 100 (имейте в виду, что один и тот же рейс, как, например, RY-1234-VY, может совершать различные поездки в разные дни, но не более одного в один и тот же день).

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

SELECT Airplane_Code, Day, Flight_Code
FROM Travels
WHERE (Day, Flight_Code) IN (SELECT Day, Flight_Code
                                 FROM boardings b1
                                 GROUP BY Day, Flight_Code
                                 HAVING SUM(Luggage_Weight) = (SELECT MAX(SUM(Luggage_Weight))
                                                              FROM boardings b2
                                                              WHERE b1.Flight_Code = b2.Flight_Code
                                                              GROUP BY Day, Flight_Code
                                                              HAVING SUM(Luggage_Weight) > 100))
GROUP BY Airplane_Code, Day, Flight_Code;

Я хотел бы, чтобы решение использовало структуру GROUP BY и HAVING.

Например:

INSERT INTO travels VALUES ('04/04/2020', 'RY1234', 'ABCD');
INSERT INTO travels VALUES ('03/04/2020', 'RY1234', 'ABCD');

INSERT INTO boardings VALUES ('ES1234', '04/04/2020', 'RY1234', '51');
INSERT INTO boardings VALUES ('ES5678', '04/04/2020', 'RY1234', '50');
INSERT INTO boardings VALUES ('ES9101', '03/04/2020', 'RY1234', '100');

Как вы можете видеть, один и тот же рейс (RY1234) прошел за 2 разных дня, поэтому в 03/04 общий вес багажа составил 100 кг, но в 04/04 общий вес багажа составил 101 кг. Результат должен быть следующим:

ABCD ---- 04/04/2020 ---- RY1234

В случае, если он не набрал бы 100 кг ни на одном из своих полетов для того же самолета, этот код самолета не должен отображаться.

Ответы [ 3 ]

1 голос
/ 04 апреля 2020

Вы можете использовать dense_rank() в производной таблице, чтобы ранжировать полеты по sum() их весам. Затем присоедините это к travels и отфильтруйте для ранга 1.

SELECT t.airplane_code,
       t.day,
       t.flight_code
       FROM travels t
            INNER JOIN (SELECT b.day,
                               b.flight_code,
                               dense_rank() OVER (ORDER BY sum(b.luggage_weight) DESC) dr
                               FROM boardings b
                               GROUP BY b.day,
                                        b.flight_code) x
                       ON x.day = t.day
                          AND x.flight_code = t.flight_code
            WHERE x.dr = 1;

db <> fiddle

0 голосов
/ 05 апреля 2020

Вы можете использовать рефакторинг подзапроса вместе с GROUP BY и HAVING, как показано ниже, чтобы получить свой результат.

Когда вы говорите ниже, вам нужно сгруппировать только по Flight_code, чтобы получить максимальный вес.

Итак, я пытаюсь сделать запрос, чтобы увидеть для каждого самолета, который был рейс (Day и Flight_Code), что он перевозил максимальный вес, будучи всегда больше 100 (имейте в виду, что один и тот же рейс, как, например, RY-1234-VY, может совершать разные поездки в разные дни, но не более одного в тот же день).

            WITH t
             AS (SELECT t.airplane_code,
                        t.day,
                        t.flight_code,
                        SUM(luggage_weight) wt
                 FROM   travels t,
                        boardings b
                 WHERE  t.flight_code = b.flight_code
                        AND Trunc(t.day) = Trunc(b.day)
                 GROUP  BY t.airplane_code,
                           t.day,
                           t.flight_code
                 HAVING SUM(luggage_weight) > 100),
             t1
             AS (SELECT Max(wt) wt,
                        flight_code
                 FROM   t
                 GROUP  BY
                           flight_code)
        SELECT t.*
        FROM   t,
               t1
        WHERE  t.wt = t1.wt
               AND t.flight_code = t1.flight_code 

Без подзапроса с рефакторингом можно использовать как ниже

 SELECT t.airplane_code,
           t.day,
           t.flight_code
    FROM   travels t,
           boardings b
    WHERE  t.flight_code = b.flight_code
           AND Trunc(t.day) = Trunc(b.day)
    GROUP  BY t.airplane_code,
              t.day,
              t.flight_code
    HAVING SUM(luggage_weight) IN (SELECT Max(wt) wt
                                   FROM   (SELECT b.day,
                                                  b.flight_code,
                                                  SUM(luggage_weight) wt
                                           FROM   boardings b
                                           GROUP  BY b.day,
                                                     b.flight_code
                                           HAVING SUM(luggage_weight) > 100)rec
                                   WHERE  rec.flight_code = t.flight_code
                                   GROUP  BY t.flight_code)

вы также можете использовать что-то вроде ниже

   SELECT *
    FROM   travels t
    WHERE  ( Trunc(t.day), t.flight_code ) IN (SELECT Trunc(b.day),
                                                      b.flight_code
                                               FROM   boardings b
                                               GROUP  BY b.day,
                                                         b.flight_code
                                               HAVING SUM(luggage_weight) IN
                                                      (SELECT Max(wt) wt
                                                       FROM
                                              (SELECT b.day,
                                                      b.flight_code,
                                                      SUM(luggage_weight)
                                                      wt
                                               FROM   boardings b
                                               GROUP  BY b.day,
                                                         b.flight_code
                                               HAVING SUM(luggage_weight) >
                                                      100)rec
                                                       WHERE
                  rec.flight_code = b.flight_code
0 голосов
/ 04 апреля 2020
select Airplane_Code,day,Flight_Code from (
Select Airplane_Code,day,Flight_Code ,sum(Luggage_Weight) over (Partition by 
Flight_Code,day) as total_weight
from travels t,boardings b
where t.Flight_Code=b.Flight_Code)data1
where data1.total_weight >100;
...