【问题标题】:Making a MAX() query from a subquery with COUNT()使用 COUNT() 从子查询进行 MAX() 查询
【发布时间】:2019-10-23 20:32:56
【问题描述】:

需要显示旅行次数最多的船的名称,所以我做了一个计算旅行次数的查询:

SELECT B.IdBoat, COUNT(T.IdTrip)
FROM Trip T INNER JOIN Boat B ON T.IdBoat=B.IdBoat
GROUP BY B.IdBoat

现在我需要显示具有 MAX 行程的人的名称,我如何将该查询用作子查询,而不使用 ORDER BY DESC 和 TOP 1 但使用 MAX? 目前得到:

SELECT B.Name
FROM Trip T INNER JOIN Boat B ON T.IdBoat=B.IdBoat
WHERE B.IdBoat = MAX( the sub query above)

也试过了

SELECT B.Name, T.IdTrip
FROM Boat B INNER JOIN Trip T ON B.IdBoat=T.IdBoat
WHERE B.IdBoat IN (
SELECT MAX(T.NTrips) FROM 
    (SELECT B.IdBoat AS [IdBoat], COUNT(T.IdTrip) AS [NTrips]
    FROM Trip T INNER JOIN Boat B ON B.IdBoat=T.IdBoat
    GROUP BY B.Boat) T
    GROUP BY T.IdBoat)

上面返回的是船名上的完整计数 3,而不是正确的 2。

我已经尝试在 stackoverflow 和其他人上搜索和搜索上述问题,但无法根据我的查询调整他们的解决方案,任何帮助都是很好的帮助。

谢谢。

编辑 1. 如要求,我将提供一些数据以帮助更好地理解问题

桌船:

IdBoat | Name
1      | 'SS Sparrow'
2      | 'SS AndaNoMar'

餐桌旅行

IdTrip | IdBoat
1      | 1
2      | 1
3      | 2

子查询 1 (COUNT)

IdBoat | NTrips
2      | 1
1      | 2

【问题讨论】:

标签: sql sql-server


【解决方案1】:

你可以这样做:

with
x as (
  select
    b.idBoat,
    b.Name,
    count(*) as cnt
  from trip t
  join boat b on b.idBoat = t.idBoat
  group by b.idBoat, b.Name
),
m as (
  select max(cnt) as max_cnt from x
)
select 
  x.*
from x
join m on m.max_cnt = x.cnt

【讨论】:

  • 我认为您还需要在 group by 子句中添加 b.Name。
  • 还有一个逗号在 SELECT 块中
  • 抱歉耽搁了,我花了一些时间来适应/理解代码,但它确实有效,直到现在我从未使用过 WITH 命令,也不知道这是一个选项。感谢您提供的代码,我现在将尝试更好地理解它。
  • @MOI 否,如果idBoat 是表的主键,则GROUP BY 子句中不需要b.Name。 SQL 标准允许GROUP BY 子句中不存在“直接依赖列”。
  • @TheImpaler 它会在 mssql 中工作还是只在 mysql 中工作?我按照你说的试过了,但它在 mssql 中对我不起作用。我在msdn上找不到。所以,如果你有一个链接,我可以阅读你所说的关于 group by 条款的标准,请分享。
【解决方案2】:
SELECT
  B.IdBoat,
  B.Name,
  T.Trips
FROM
  Boat  AS B
INNER JOIN
(
  SELECT
    IdBoat,
    COUNT(*)  AS Trips,
    RANK() OVER (PARTITION BY IdBoat
                     ORDER BY COUNT(*) DESC
                )
                  AS TripsRank
  FROM
    Trip
  GROUP BY
    IdBoat
)
  AS T
    ON T.IdBoat = B.IdBoat
WHERE
  T.TripsRank = 1

【讨论】:

    【解决方案3】:

    比其他两个答案更好的方法是使用ORDER BY

    SELECT TOP (1) B.IdBoat, B.Name, COUNT(T.IdTrip) as cnt
    FROM Trip T INNER JOIN
         Boat B 
         ON T.IdBoat = B.IdBoat
    GROUP BY B.IdBoat, B.Name
    ORDER BY cnt DESC;
    

    不需要子查询、CTE 或窗口函数。

    如果你想打领带,那么你可以使用TOP (1) WITH TIES

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 2011-12-11
      • 2020-10-07
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 2021-07-08
      相关资源
      最近更新 更多