从起降点获取前10名机场名称

时间:2018-08-24 17:26:06

标签: sql sql-server

我的情况似乎很简单,但是当我尝试实现它时,情况就变得复杂了:我想向客户提供他的“最喜欢的机场”。

也许我只是愚蠢而没注意到一个小事……

应该做什么

  • COUNT Start中每个机场的LandingBookings s
  • 使用TOP 10个机场ID s和COUNT
  • Name获取Airport

表和列

预订:

  • 飞机场:int FOREIGN KEY Airports.ID
  • 着陆机场:int FOREIGN KEY Airports.ID

机场

  • ID:int PRIMARY KEY
  • 名称:varchar

当前状态

我的查询如下(这是我得到的距离):

SELECT
    ttl.Start_Airport,
    ttl.Landing_Airport
FROM
    (
        SELECT
            COUNT(Start_Airport) AS Start_Airport_Count,
            COUNT(Landing_Airport) AS Landing_Airport_Count,
            Start_Airport, Landing_Airport
        FROM
            Bookings
        WHERE
            (
                Start_Airport <> 0 OR
                Landing_Airport <> 0
            )
        GROUP BY
            Start_Airport, Landing_Airport
        ) AS ttl
HAVING
  ttl.Start_Airport_Count = MAX(ttl.Start_Airport_Count) OR
  ttl.Landing_Airport_Count = MAX(ttl.Landing_Airport_Count)

问题

目前,它说Start_Airport_CountLanding_Airport_Count必须在GROUP BY子句中,但是我得到的结果却与预期不同。

谢谢!

3 个答案:

答案 0 :(得分:2)

我将取消透视和聚合:

select top (10) a.name, count(*)
from books b cross apply
     (values (Start_Airport), (Landing_Airport)) v(airport) join
     airports a
     on v.airport = a.id
group by a.name
order by count(*) desc;

我很确定这是最短,最高效的方法。

答案 1 :(得分:1)

如果我正确理解,则需要类似以下内容的

SELECT Airports.name as Airport, t1.cnt as Start_Airport_count, t2.cnt as Landing_Airport_count
FROM (
    select Start_Airport as a_id, count(*) as cnt from  Bookings 
    group by Start_Airport 
) t1
FULL JOIN (
    select Landing_Airport as a_id, count(*) as cnt from  Bookings 
    group by Landing_Airport
) t2
ON t1.a_id =  t2.a_id 
INNER JOIN Airports
ON coalesce(t1.a_id, t2.a_id) = Airports.id
ORDER BY coalesce(t1.cnt,0) + coalesce(t2.cnt,0) DESC 
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY

答案 2 :(得分:1)

这是垂直格式的刺伤。我看不到一种横向的干净方法,因为您可能会对喜欢的出发/到达点数有所不同。

我创建简单的变量表,计算开始/着陆发生的次数,然后以递减的方式对这些计数进行排序(最高= 1)。

然后我输出每个组中排名最高的机场的结果。

DECLARE @Bookings TABLE (Start_Airport INT, Landing_Airport INT)
DECLARE @Airports TABLE (Id INT, Name VARCHAR(50))

INSERT INTO @Airports(Id,Name)
VALUES (1,'New York'),
       (2,'Miami'),
       (3,'London'),
       (4,'Sydney'),
       (5,'Tokyo'),
       (6,'Los Angeles')

INSERT INTO @Bookings (Start_Airport,Landing_Airport)
VALUES (1,2),
       (1,3),
       (6,4),
       (6,5),
       (3,2),
       (3,4),
       (3,6),
       (5,3),
       (5,2),
       (4,2)

;WITH X AS
(
    SELECT *, COUNT(2) OVER(PARTITION BY Start_Airport) AS numOfDepartures,
              COUNT(2) OVER(PARTITION BY Landing_Airport) AS numofArrivals
    FROM @Bookings
), Y AS 
    (
        SELECT *, RANK() OVER(ORDER BY numOfDepartures DESC) AS rankDepartures,
                  RANK() OVER(ORDER BY numofArrivals DESC) AS rankArrival
        FROM X
    )

SELECT DISTINCT A.Name, numOfDepartures as flightCount, rankDepartures as airportRank, 'Top Departing Location' as Info
FROM Y 
JOIN @Airports A ON Y.Start_Airport=A.Id
WHERE rankDepartures=1
UNION
SELECT DISTINCT A.Name, numofArrivals, rankArrival, 'Top Arriving Location'
FROM Y 
JOIN @Airports A ON Y.Landing_Airport=A.Id
WHERE rankArrival=1
ORDER BY Info, Name