Query to see the MAX value in Oracle

三世轮回 提交于 2020-03-25 18:56:05

问题


I have the following N:N table (which stores the people boardings) in my Oracle Database (it is about an airport):

CREATE TABLE boardings(
Passport VARCHAR2(8),
Day DATE,
Flight VARCHAR2(8),
LuggageWeight NUMBER(4,2),
CONSTRAINT pk PRIMARY KEY(Passport, Day, Flight));

And I would like to make a query in order to see for each flight, which has been the day that has transported the highest amount of weight (keep in mind that a same flight, as RY-1234-VY for example, can make different travels in different days. I have been trying something like this, but it doesn't work:

SELECT Day, Flight
FROM test
GROUP BY Day, Flight
HAVING SUM(LuggageWeight) = (SELECT MAX(SUM(LuggageWeight))
                             FROM test
                             GROUP BY Day, Flight);

回答1:


I think you were close.

SELECT Day, Flight
FROM boardings b1
GROUP BY Day, Flight
HAVING SUM(LuggageWeight) = (SELECT MAX(SUM(LuggageWeight))
                             FROM boardings b2
                             where b1.Flight = b2.Flight -- I have added this line
                             GROUP BY day, flight);

Here is a demo

Something like this? :

SELECT Flight, Day
FROM boardings b1
where (Flight, Day) = (SELECT Flight, Day
                     FROM boardings b2
                     where b2.flight = b1.flight
                     GROUP BY Flight, Day
                     order by SUM(LuggageWeight) desc
                     fetch first 1 rows only)



回答2:


There are several ways to approach this.

You can run the aggregation once in a common table expression and use that in a sub-query.

with totals as (
  SELECT Day, Flight, SUM(LuggageWeight) total_weight
  FROM test
  GROUP BY Day, Flight
)
select *
from totals
where total_weight = (select max(total_weight) from totals);

Or combine the grouping with window functions:

select day, flight, total_weight
from (
  SELECT Day, Flight, 
         SUM(LuggageWeight) total_weight,
         dense_rank() over (order by SUM(LuggageWeight) desc) as rnk
  FROM test
  GROUP BY Day, Flight
) totals
where rnk = 1;

The above can easily be extended to also include the 2nd heaviest flight and so on. The derived table (sub-query) totals is essentially only necessary because of visibility rules.

And if you are only interested in a single row, even if there is more than one day/flight combinations with the same (highest) total weight, you can use:

SELECT Day, Flight, SUM(LuggageWeight) total_weight
FROM test
GROUP BY Day, Flight
order by SUM(LuggageWeight) desc
fetch first 1 rows only;

Again: the above is not exactly the same as the other solutions, but might be good enough.




回答3:


I'd break this problem into two mental steps. First, you need to sum the weight per flight per day, which can be done by calling sum in a query grouped by the flight and date. Then, for each flight, you need to find the top day, which can be done with the rank window function:

SELECT day, flight, sum_weight
FROM   (SELECT day, flight, sum_weight,
               RANK() OVER (PARTITION BY flight ORDER BY sum_weight DESC) AS rk
        FROM   (SELECT   day, flight, SUM(LuggageWeight) AS sum_weight
                FROM     boardings
                GROUP BY day, flight) t1
       ) t2
WHERE  rk = 1



回答4:


And I would like to make a query in order to see for each flight, which has been the day that has transported the highest amount of weight (keep in mind that a same flight, as RY-1234-VY for example, can make different travels in different days.

One solution uses window functions:

SELECT b.*
FROM (SELECT Day, Flight, SUM(LuggageWeight) as TotalWeight,
             RANK() OVER (PARTITION BY Flight ORDER BY SUM(LuggageWeight) DESC) a seqnum
      FROM boardings b
      GROUP BY Day, Flight
     ) b
WHERE seqnum = 1 

One solution uses two levels of aggregation:

SELECT Flight, MAX(TotalWeight),
       MAX(Day) KEEP (DENSE_RANK FIRST ORDER BY TotalWeight DESC) as Day
FROM (SELECT Day, Flight, SUM(LuggageWeight) as TotalWeight,
             RANK() OVER (PARTITION BY Flight ORDER BY SUM(LuggageWeight) DESC) a seqnum
      FROM boardings b
      GROUP BY Day, Flight
     ) b
GROUP BY flight;


来源:https://stackoverflow.com/questions/60681353/query-to-see-the-max-value-in-oracle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!