我的情况似乎很简单,但是当我尝试实现它时,情况就变得复杂了:我想向客户提供他的“最喜欢的机场”。
也许我只是愚蠢而没注意到一个小事……
COUNT
Start
中每个机场的Landing
和Bookings
s TOP 10
个机场ID
s和COUNT
个Name
获取Airport
预订:
int FOREIGN KEY Airports.ID
int FOREIGN KEY Airports.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_Count
和Landing_Airport_Count
必须在GROUP BY
子句中,但是我得到的结果却与预期不同。
谢谢!
答案 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