【问题标题】:sql oracle top 3 visited countries query from multiple tablessql oracle top 3 访问国家/地区查询从多个表
【发布时间】:2022-01-15 23:08:05
【问题描述】:

我为航班设计了一个订票系统。在我做了一些插入之后,我想写一个查询来显示前 3 个访问过的国家。

这是我写的:

select * from ( select flightnumber, count(*) as NumberOfFlights from ticket group by flightnumber order by NumberOfFlights desc) where rownum < 4;

我的问题是如何从 Airport 表中选择 Country 列,以便在当前查询结果列“FlightNumber”和“NumberOfFlights”中添加与 FlightNumber 对应的“Country”名称。

一个例子: 机场表

insert into airport(icao_code, name, city, country) values ('PJAN', 'IS Airport', 'Iasi', 'Romania');
insert into airport(icao_code, name, city, country) values ('SBJN', 'SB Airport', 'Sibiu', 'Romania');
insert into airport(icao_code, name, city, country) values ('TMAN', 'TM Airport', 'Timisoara', 'Romania');
insert into airport(icao_code, name, city, country) values ('CJAN', 'CJ Airport', 'Cluj', 'Romania');
insert into airport(icao_code, name, city, country) values ('TKAN', 'TK Airport', 'Cluj', 'Turkey');
insert into airport(icao_code, name, city, country) values ('UKAN', 'UK Airport', 'London', 'UK');
insert into airport(icao_code, name, city, country) values ('ITAN', 'IT Airport', 'Roma', 'Italy');
insert into airport(icao_code, name, city, country) values ('SPAN', 'SP Airport', 'Madrid', 'Spain');
insert into airport(icao_code, name, city, country) values ('FRAN', 'FR Airport', 'Paris', 'France');
insert into airport(icao_code, name, city, country) values ('DEAN', 'DE Airport', 'Berlin', 'Germany');
insert into airport(icao_code, name, city, country) values ('GRAN', 'GR Airport', 'Athens', 'Greek');

飞行表

insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(1,to_date('2022/11/01 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/11/01 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 1200,'PJAN', 'GRAN',500,231);
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(2,to_date('2022/02/15 08:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/02/16 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 1200,'SBJN', 'GRAN',500,232);
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(3,to_date('2022/10/01 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/10/02 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 1200,'GRAN', 'CJAN',400,232);
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(4,to_date('2022/09/01 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/09/02 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 1200,'GRAN', 'TMAN',700,152);
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(5,to_date('2022/08/01 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/08/02 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 1200,'PJAN', 'GRAN',600,231);

--Paris-Berlin/Berlin-Paris
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(6,to_date('2022/05/06 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/05/06 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 800,'FRAN', 'DEAN',300,152);
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(7,to_date('2022/05/07 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/05/07 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 800,'DEAN', 'FRAN',300,152);

-- Spain-Turkey/Turkey-Spain
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(8,to_date('2022/05/07 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/05/09 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 4000,'SPAN', 'TKAN',800,112);
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(9,to_date('2022/05/08 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/05/10 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 4000,'SPAN', 'TKAN',800,112);
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(10,to_date('2022/05/17 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/05/19 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 4000,'TKAN', 'SPAN',800,112);
insert into flight(flightnumber,departuretime,arrivaltime,distanceinkm,airportid_departure, airportid_arrival,numberofseats,airline_id) values
(11,to_date('2022/05/18 09:00:00', 'YYYY/MM/DD HH:MI:SS'),  to_date('2022/05/20 12:00:00', 'YYYY/MM/DD HH:MI:SS'), 4000,'TKAN', 'SPAN',800,112);

票务表

insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(1,200,'1232sde2asmd',7,37);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(2,210,'1232sde2asnd',7,36);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(3,250,'1232sde2astd',7,35);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(4,270,'1232sde2as2d',7,34);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(5,280,'1232sde2as0d',4,33);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(6,300,'1232sde2as9d',4,32);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(7,100,'1232sdv2as3d',4,31);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(8,200,'1232vde2as4d',1,30);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(9,120,'1252sde2as3d',2,29);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(10,290,'1232sde2ax3d',3,28);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(11,50,'1232sdy2as3d',3,27);
insert into ticket(ticketnumber, price, confirmationcode, flightnumber, passengerid) values
(12,90,'1232sae2as3d',6,26);

在机票表中,我插入了 4 个飞往法国的航班、3 个飞往希腊的航班和另外 2 个飞往希腊的航班(我的错误)。应该是另一个国家。

所以我的查询给了我:

FlightNumber     NumberOfFlights
7                  4
4                  3
3                  2

我想要这样的结果:

FlightNumber    Country                            NumberOfFlights
7             France                                  4
4             Greece                                  3
3             Greece(mistake,some random country)     2

【问题讨论】:

  • SQL Server 还是 Oracle?
  • 我已经假设 Oracle,基于标题。
  • @Larnu 我假设 Oracle 基于语法 to_date
  • 对于前 n 个查询,您必须始终决定如何处理关系。如果排名靠前的国家有 4、4、3 和 3 次访问,而所有其他国家有 2 次或更少的访问,您希望显示哪个?只有两个有 4 次访问?四个国家?任意选择访问的两个国家和访问三个的国家之一?

标签: sql oracle


【解决方案1】:

您需要将表格连接在一起,然后按国家/地区分组。

在 Oracle 12c 上,您甚至可以使用较新的 offset 语法,这也适用于 SQL Server。

select
  a.country,
  count(*) as NumberOfTickets
from ticket as t
join flight as f on f.flightnumber = t.flightnumber
join airport as a on a.icao_code = f.airportid_arrival
group by
  a.country
order by
  NumberOfFlights desc
offset 0 rows fetch next 3 rows only;

如果您想获得前三名航班,您可以将flightnumber 添加到group by

select
  t.flightnumber,
  a.country,
  count(*) as NumberOfTickets
from ticket as t
join flight as f on f.flightnumber = t.flightnumber
join airport as a on a.icao_code = f.airportid_arrival
group by
  t.flightnumber,
  a.country
order by
  NumberOfFlights desc
offset 0 rows fetch next 3 rows only;

db<>fiddle

【讨论】:

    【解决方案2】:

    也许使用 oracle rank 函数。对于 oracle 11g 来说是这样的:

    select *
     from (select country, flightCnt, dense_rank () over( order by flightCnt) as rnk
      from (select a.country, count(f.flightNumber) as flightCnt
        from ticket t, flight f, airport a
        where t.flightNumber = f.flightNumber
        and f.airportId_arrival = a.icao_code
        group by a.country)
      )
    where rnk < 4
    ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多