【问题标题】:SQL query, return the most popular category for each citySQL查询,返回每个城市最受欢迎的分类
【发布时间】:2022-11-23 01:51:48
【问题描述】:

一直在为这个问题苦苦挣扎,无法弄清楚。我的简化表架构是:

  1. SalesOrderHeader(SalesOrderID int,ShipToAddressID int),
  2. SalesOrderDetails(SalesOrderID int,ProductID int),
  3. 地址(ShipToAddressID int,城市 nvarchar),
  4. 产品(产品 ID 整数,产品类别整数)
  5. ProductCategory(ProductCategoryID int,名称 nvarchar)。

    我试图找到 3 个最受欢迎的城市(交付订单最多的城市)以及这些城市中最受欢迎的产品类别,但不幸的是,无法正常工作。

    select count(*) as OrderNum, ProductCategory.Name, City from SalesLT.SalesOrderDetail
     left join SalesLT.SalesOrderHeader on SalesLT.SalesOrderDetail.SalesOrderID = SalesLT.SalesOrderHeader.SalesOrderID
     left join SalesLT.Address on SalesLT.Address.AddressID = SalesOrderHeader.ShipToAddressID
     left join SalesLT.Product on SalesOrderDetail.ProductID = Product.ProductID
     left join SalesLT.ProductCategory on ProductCategory.ProductCategoryID = Product.ProductCategoryID
     where City in 
    (select top(3) City from SalesLT.SalesOrderHeader
    left join SalesLT.Address on SalesLT.Address.AddressID = SalesOrderHeader.ShipToAddressID
    group by City
    order by Count(*) desc)
    group by City, ProductCategory.Name
    order by count(*) desc
    

    我试图更改查询以使其只为每个城市返回 1 个位置,但没有成功。很高兴听到建议,谢谢。

    Query returns following result

【问题讨论】:

  • 请添加几行示例数据和预期结果。

标签: sql sql-server


【解决方案1】:

您可以使用 ROW_NUMBER() 窗口函数为按城市分区并按降序计数排序的每个结果分配序列号。如果将其包装在公用表表达式 (CTE) 中,则可以添加最终选择,它只选择每个城市的顶部(行号 = 1)行。

就像是:

with CTE as (
    select
        count(*) as OrderNum,
        ProductCategory.Name,
        City,
        row_number() over(partition by City order by count(*) desc) as RN
    from SalesLT.SalesOrderDetail
     left join SalesLT.SalesOrderHeader on SalesLT.SalesOrderDetail.SalesOrderID = SalesLT.SalesOrderHeader.SalesOrderID
     left join SalesLT.Address on SalesLT.Address.AddressID = SalesOrderHeader.ShipToAddressID
     left join SalesLT.Product on SalesOrderDetail.ProductID = Product.ProductID
     left join SalesLT.ProductCategory on ProductCategory.ProductCategoryID = Product.ProductCategoryID
    where City in (
        select top(3) City
        from SalesLT.SalesOrderHeader
        left join SalesLT.Address on SalesLT.Address.AddressID = SalesOrderHeader.ShipToAddressID
        group by City
        order by Count(*) desc
    )
    group by City, ProductCategory.Name
)
select OrderNum, Name, City
from CTE
where RN = 1
order by City

如果您想在每个城市显示多个类别(比如前 3 个),您可以将最终条件调整为类似 where RN <= 3 的内容。

如果您想更好地处理平局(显示具有相同高计数的所有类别),您可以使用 RANK() 而不是 ROW_NUMBER()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多