You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

聚合数据查询异常:如何获取各书店库存最高书籍的对应标题?

解决书店库存最高书籍的查询问题

我们有一个包含3家书店的数据库,每家书店对应库存表,书籍库存数量随机。需求是查询展示:每家书店(共3行)、该书店库存最高的书籍数量(通过MAX(INV.UnitsInStock)计算)以及对应书籍的标题。

之前尝试的问题

第一次编写的SQL:

SELECT BS.Name, B.Title, MAX(UnitsInStock) AS 'Quantity'
FROM Inventories AS INV
JOIN BookShops AS BS ON BS.Id = INV.ShopId
JOIN Books AS B ON B.Id = INV.BookId
GROUP BY BS.Name

运行后报错:

Column 'Books.Title' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

第二次SQL能得到书店名和最高库存,但缺少书籍标题:

SELECT BS.Name, MAX(UnitsInStock) AS 'Quantity'
FROM Inventories AS INV
JOIN BookShops AS BS ON BS.Id = INV.ShopId
JOIN Books AS B ON B.Id = INV.BookId
GROUP BY BS.Name

可行解决方案

方案1:窗口函数(推荐,灵活处理并列情况)

利用窗口函数给每家书店的库存记录排序,筛选出排名第一的条目。根据是否需要保留并列最高的书籍,选择ROW_NUMBER()或RANK():

仅返回单本(随机选一本,若有并列)

如果书店存在多本库存并列最高的书籍,这个方法会随机选取其中一本返回:

WITH RankedInventory AS (
    SELECT 
        BS.Name AS ShopName,
        B.Title,
        INV.UnitsInStock AS Quantity,
        -- 按书店分组,库存降序排序,给每条记录编号
        ROW_NUMBER() OVER (PARTITION BY BS.Id ORDER BY INV.UnitsInStock DESC) AS RowNum
    FROM Inventories AS INV
    JOIN BookShops AS BS ON BS.Id = INV.ShopId
    JOIN Books AS B ON B.Id = INV.BookId
)
SELECT ShopName, Title, Quantity
FROM RankedInventory
WHERE RowNum = 1;

返回所有并列最高的书籍

如果需要把书店里所有库存达到最高值的书籍都列出来,改用RANK():

WITH RankedInventory AS (
    SELECT 
        BS.Name AS ShopName,
        B.Title,
        INV.UnitsInStock AS Quantity,
        -- 并列最高的记录会获得相同排名
        RANK() OVER (PARTITION BY BS.Id ORDER BY INV.UnitsInStock DESC) AS RankNum
    FROM Inventories AS INV
    JOIN BookShops AS BS ON BS.Id = INV.ShopId
    JOIN Books AS B ON B.Id = INV.BookId
)
SELECT ShopName, Title, Quantity
FROM RankedInventory
WHERE RankNum = 1;

方案2:子查询关联匹配最高库存

先计算每家书店的最高库存值,再关联回原表找到对应的书籍信息:

SELECT 
    BS.Name AS ShopName,
    B.Title,
    INV.UnitsInStock AS Quantity
FROM Inventories AS INV
JOIN BookShops AS BS ON BS.Id = INV.ShopId
JOIN Books AS B ON B.Id = INV.BookId
-- 子查询算出每家书店的最高库存
JOIN (
    SELECT ShopId, MAX(UnitsInStock) AS MaxStock
    FROM Inventories
    GROUP BY ShopId
) AS MaxInv 
    ON INV.ShopId = MaxInv.ShopId 
    AND INV.UnitsInStock = MaxInv.MaxStock;

这个方法同样会返回所有库存并列最高的书籍,结果和用RANK()的窗口函数一致。


内容的提问来源于stack exchange,提问作者Jonathan Lind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:20:36