【问题标题】:How to rank an aggregation in each newly formed group?如何在每个新成立的组中对聚合进行排名?
【发布时间】:2019-12-21 03:26:57
【问题描述】:

下面我想解决的问题听起来很简单,但我很难用 SQL 得出解决方案。

假设我有一个简化的 ERD,如下所示:

这是一个假设的电影流媒体网站的数据库,其中保存有关其客户、发票、电影及其类型的数据。每个客户都有一个唯一的 CustomerID,每次购买都有一个唯一的 InvoiceID,每部电影都有一个唯一的 MovieID,每个流派都有一个唯一的 GenreID。一个 MovieID 只与一个 GenreID 相关联。一位客户可以购买多部电影,因此一张 Invoice 可以包含多个 MovieID。

我想显示以下每个大洲/地区中最受欢迎的 2 个类型(以 InvoiceID 的总数计): 非洲(埃及、南非)、亚洲(中国、日本)、欧洲(法国、德国)。

Customer 和 Genre 表的示例如下:

我想要的结果表看起来或多或少像这样(区域表示大陆):

生成的表格到底长什么样并不重要,我只想要按每个地区分组的前 2 个类型。

以下是我在生成查询时所做的一些努力:

WITH t1 AS (
      SELECT c.Country,
      CASE
        WHEN (
          (c.Country = "China" OR c.Country = "Japan") THEN "Asia"
        )
        WHEN (
          (c.Country = "Egypt" OR c.Country = "South Africa") THEN "Africa"
        )
        ELSE "Europe"
      END AS region
    FROM Customer c
    GROUP BY 1
    )

SELECT DISTINCT region
FROM t1;

我只能制作新的地区组,但在如何对按地区分组的流派进行排名时遇到了困难。我很难显示每个地区的流派排名(基于 InvoiceID 的总数)。换句话说,在每个地区,有多少客户购买了每种类型。我刚刚开始学习 SQL,其中包括不同类型的 JOINS、SUBQUERY、AGGREGATIONS、GROUP BY、ORDER BY 和 Common Table Expression,但不知何故我无法产生我想要的结果。有人可以说明一下吗?提前感谢您的帮助。

【问题讨论】:

  • 我删除了不一致的数据库标签。请标记您真正使用的数据库。
  • @GordonLinoff 抱歉,我添加了 sqlite 标签。谢谢。

标签: sql postgresql join subquery


【解决方案1】:

demo:db<>fiddle

WITH cte AS (
    SELECT
        CASE WHEN country IN ('FR','GER') THEN 'europe'
             WHEN country IN ('CHI', 'JAP') THEN 'asia'
        END AS region,
        genre_name
    FROM
        joined_table
)
SELECT
    region, genre_name
FROM (
    SELECT
        region,
        genre_name,
        row_number() OVER (PARTITION BY region ORDER BY COUNT(*) DESC)
    FROM cte
    GROUP BY region, genre_name
) s
WHERE row_number <= 2
  1. CTE 用于将国家/地区转换为区域(显然,使用的表是通过您的结构替换整个连接的)
  2. regiongenre_name 分组并计算类型。
  3. 这个COUNT 可用于为每个区域生成一个row_number(),按计数降序排列以将最高计数排在顶部。所以最有趣的流派成为每个组的第一张唱片
  4. 过滤两个最高记录。

【讨论】:

  • 谢谢。还有一个问题,当我尝试使用 sqlit 运行它时,它返回一个错误,上面写着 ' near "(": syntax error '。你知道如何解决它吗?非常感谢。
  • 对不起,我赞成你的回答,你能帮忙看看 sqlite 语法吗?我已经尝试在网上搜索如何在 sqlite 中使用 row_number,但仍然无法解决错误。感谢您的帮助。
猜你喜欢
  • 2022-01-07
  • 2012-08-31
  • 2021-05-30
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-10
相关资源
最近更新 更多