简体   繁体   中英

How to get count of two columns of a table based on PK of another table?

I have two tables defined as:

CREATE TABLE airports (
  code char(3) not null primary key,
  name varchar(100) not null,
  city varchar(50) not null,
  state varchar(5),
  country char(2) not null references fcountries(code)
)

and

CREATE TABLE flights (
  departure char(3) not null references airports(code), -- airport code
  arrival char(3) not null references airports(code), -- airport code
  dep_time time not null,
  airline char(2) not null references airlines(code)
)

I need to get the number of flights departing from and arriving at an airport using postgres. So, I wrote

select
  code,
  count(departure)
from airports 
join flights 
 on flights.departure = airports.code group by code;

and for departure similarily,

select
  code,
  count(arrival) as Arrival
from airports 
join flights 
  on flights.arrival = airports.code group by code;

But I need to combine these two and get the arrival-departure count in the same result. I am not sure how to do it? I wrote this query

select
  code,
  count(departure),
  x.arrival
from (
  select count(arrival) as arrival
  from airports 
  join flights 
    on flights.arrival = airports.code group by code
) x, 
airports 
join flights on airports.code = flights.departure
group by code, x.arrival
order by code;

But the result is not correct as 'code' is repeated in this result. I am pretty new to sql and not sure how to write this.

The simplest method is a lateral join and group by :

select v.code, count(*) as total,
       sum(is_departure) as num_departures,
       sum(is_arrival) as num_arrivals
from flights cross join lateral
     (values (departure, 1, 0), (arrival, 0, 1)
     ) as v(code, is_departure, is_rrival)
     on f.departure = a.code
group by v.code;

Note that the JOIN to airports is unnecessary, unless you actually want to bring in more information that you haven't mentioned in the question.

You could use the two query as subquery and join

    select t1.code,  t1.count_departure, t2.count_arrival 
    from (
        select code, count(departure)  count_departure
        from airports join flights on flights.departure = airports.code 
        group by code

    ) t1  
    inner join  (
        select code, count(arrival) as  count_arrival 
        from airports join flights on flights.arrival = airports.code 
        roup by code

    ) t2 on t1.code  = t2.code ;

I think alias t2 cannot be used like that after join that's why you are getting the error. Try this:

select t1.code, t1.count_departure, t2.count_arrival from ( select code, count(departure) count_departure from airports join flights on flights.departure = airports.code group by code ) t1 join ( select code, count(arrival) as count_arrival from airports join flights on flights.arrival = airports.code group by code ) t2 on t1.code = t2.code;

A quite simple method is just to use a correlated COUNT subquery in the SELECT clause:

select a.code,
    (select count(*) from flights f where f.departure = a.code) as departures,
    (select count(*) from flights f where f.arrival = a.code) as arrivals
from airports a;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM