我有4张桌子:
Travelers (TravelerID,FirstName,LastName)
Guides(GuideID,FirstName,LastName)
Locations(LocationID,LocationName)
Trips(TravelerID,GuideID,LocationID,Stars,StartDate,ReturnDate)
我想按指南返回他引导最多旅行者人数的位置名称。
我尝试过使用这个子查询,但它不起作用:
SELECT G.FirstName,L.LocationName,count(distinct(TravelerID))as number_of_travelers_per_guide
FROM Guides AS G
LEFT JOIN Trips AS T USING (GuideID)
LEFT JOIN Locations AS L USING (LocationID)
GROUP BY G.FirstName,L.LocationName
HAVING max((SELECT T1.number_of_travelers_per_guide
FROM Trips AS T1
WHERE T.GuideID=T1.GuideID));
我将不胜感激任何帮助
答案 0 :(得分:1)
尝试使用完整功能而不是alis
SELECT G.FirstName,L.LocationName, count(distinct T.TravelerID ) as number_of_travelers_per_guide
FROM Guides AS G
LEFT JOIN Trips AS T USING (GuideID)
LEFT JOIN Locations AS L USING (LocationID)
GROUP BY G.FirstName,L.LocationName
HAVING count(distinct TravelerID ) = (
select max(my_count) from (SELECT count(distinct T.TravelerID) my_count
FROM Guides AS G
LEFT JOIN Trips AS T USING (GuideID)
LEFT JOIN Locations AS L USING (LocationID)
GROUP BY G.FirstName, L.LocationName ) my_t );
答案 1 :(得分:1)
这是MySQL真正的痛苦,因为pre v 8版本既没有CTE也没有窗口函数。一种方法使用变量:
SELECT gl.*
FROM (SELECT gl.*,
(@rn := if(@g = gl.FirstName, @rn + 1,
if(@g := gl.FirstName, 1, 1)
)
) as rn
FROM (SELECT G.FirstName, L.LocationName, count(distinct TravelerID) as number_of_travelers_per_guide
FROM Guides G LEFT JOIN
Trips T
USING (GuideID) LEFT JOIN
Locations L
USING (LocationID)
GROUP BY G.FirstName, L.LocationName
ORDER BY G.FirstName, number_of_travelers_per_guide DESC
) gl CROSS JOIN
(SELECT @g := '', @rn := -1) params
) gl
WHERE rn = 1;
我不会强调理解MySQL中的变量。相反,请了解row_number()
,rank()
和dense_rank()
- 这些是在几乎所有数据库中解决问题的正确方法。
答案 2 :(得分:0)
如果无法使用CTE和分析功能,我认为您正在考虑以下内容。但是,如果指南有两个排名相同的位置,则会有一个危险,那么将为该指南返回两行或更多行而不是一行。
SELECT
G.FirstName
,L.LocationName
,guide_stats.traveler_count
FROM
(
SELECT
GuideID
,LocationID
,COUNT(DISTINCT TravelerID) AS traveler_count
FROM Trips
GROUP BY GuideID, LocationID
) AS guide_stats
INNER JOIN
(
SELECT
guide_stats_for_max.GuideID
,MAX(guide_stats_for_max.traveler_count) AS max_traveler_count
FROM
(
SELECT
GuideID
,LocationID
,COUNT(DISTINCT TravelerID) AS traveler_count
FROM Trips
GROUP BY GuideID, LocationID
) AS guide_stats_for_max
GROUP BY GuideID
) AS guide_max
ON (guide_stats.GuideID = guide_max.GuideID)
AND (guide_stats.traveler_count = guide_max.max_traveler_count)
LEFT JOIN Guides AS G USING (guide_stats.GuideID)
LEFT JOIN Locations AS L USING (guide_stats.LocationID)
注意我在没有测试的情况下编写了此代码 - 请原谅小错误。