【问题标题】:Getting median of column values in each group获取每组中列值的中位数
【发布时间】:2016-05-25 19:39:43
【问题描述】:

我有一个包含 user_id、movie_id、rating 的表。这些都是 INT,评分范围为 1-5。

我想获得中等评分并按 user_id 对其进行分组,但我在执行此操作时遇到了一些问题。

我现在的代码是:

SELECT AVG(rating)
FROM (SELECT rating
      FROM movie_data
      ORDER BY rating
      LIMIT 2 - (SELECT COUNT(*) FROM movie_data) % 2
      OFFSET (SELECT (COUNT(*) - 1) / 2
              FROM movie_data));

但是,这似乎返回了所有评分的中值。如何按 user_id 对其进行分组,以便查看每个用户的平均评分?

【问题讨论】:

    标签: sqlite group-by median


    【解决方案1】:

    以下给出了所需的中位数:

    DROP TABLE IF EXISTS movie_data2;
    CREATE TEMPORARY TABLE movie_data2 AS
    SELECT user_id, rating FROM movie_data order by user_id, rating;
    
    SELECT a.user_id, a.rating FROM (
    SELECT user_id, rowid, rating
    FROM movie_data2) a JOIN (
    SELECT user_id, cast(((min(rowid)+max(rowid))/2) as int) as midrow FROM movie_data2 b
    GROUP BY user_id
    ) c ON a.rowid = c.midrow
    ;
    

    逻辑简单,但代码没有美化。给予鼓励或 cmets 我会改进它。简而言之,诀窍是使用 SQLite 的rowid

    【讨论】:

    • 感谢您的回复。我认为a.user_id 正在使用行ID 是否正确?您能否简要解释一下这使我们能够做什么?此外,这会产生一些重复,即用户似乎有多个中值评分。你能解释这是为什么吗?示例输出 pastebin:pastebin.com/9fvih7Q2
    • rowid用作行号,但实际上在建表时是固定的。所以,确实,代码中有一个错误,我试图修复它,使用一个新的 TEMPORARY 表。再试一次?
    【解决方案2】:

    这并不容易,因为 SQLite 不允许相关子查询引用 LIMIT/OFFSET 子句中的外部值。

    user_id 的 WHERE 子句添加到所有三个子查询中,并为每个用户 ID 执行它们。

    【讨论】:

      【解决方案3】:
      SELECT user_id,AVG(rating) 
      FROM movie_data
      GROUP BY user_id
      ORDER BY rating
      

      【讨论】:

      • 您应该添加一些文字来解释此答案的作用以及为什么它为特定问题提供了解决方案。代码转储很少对其他人有用。
      • 感谢您的回答,但据我所知,AVG 函数返回平均值而不是中值。
      猜你喜欢
      • 1970-01-01
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 2018-11-23
      • 2012-10-06
      • 2019-02-26
      相关资源
      最近更新 更多