不同的 Group By 在 SQLAlchemy 中不起作用

Posted

技术标签:

【中文标题】不同的 Group By 在 SQLAlchemy 中不起作用【英文标题】:Distinct on Group By doesn't work in SQLAlchemy 【发布时间】:2018-11-14 03:21:11 【问题描述】:

我的问题是我应该如何使用distint() 根据一列的值删除/忽略数据库中的重复行。所以这是我的场景。

我有一个名为 test_db 的数据库,其中包含以下数据:

values_list = [
    'tweet_id': '1', 'retweet': '100', 'user_id': '101',
    'tweet_id': '2', 'retweet': '10', 'user_id': '101',    
    'tweet_id': '2', 'retweet': '11', 'user_id': '101',        
    'tweet_id': '10', 'retweet': '110', 'user_id': '102',            
    'tweet_id': '10', 'retweet': '110', 'user_id': '102',                
    'tweet_id': '110', 'retweet': '0', 'user_id': '2',                    
]

我想将定义为user_id 的每个用户的转发计数和推文计数相加。我对这样一个问题的查询如下:

q = select([
            test_db.columns.user_id,
            test_db.columns.tweet_id.distinct(),
            func.count(test_db.columns.retweet).label('count'),
            func.sum(cast(test_db.columns.retweet, Integer)).label('total_retweet'),
           ])
q = q.group_by(test_db.columns.user_id)

我得到如下:

user_id     tweet_id  count  total_retweet
102         10        2      220
101         2         3      121
2           110       1      0

但我的预期结果应该是这样的:

user_id     tweet_id  count  total_retweet
102         10        1      110
101         2         2      111
2           110       1      0

我不确定我应该如何强制执行 distinct 以获得预期的结果,或者还有其他方法可以解决这个问题。

谢谢!

【问题讨论】:

选择tweet_id 等于2 和user_id 101 的一行或另一行的逻辑是什么?我会理解这些值是否带有时间戳,并且您会选择最新的等。 正如我在预期结果中显示的那样,我选择了最大转发,但我不在乎选择了哪一个。我只是不知道在这种情况下应该如何工作。 【参考方案1】:

通过阅读this post 关于嵌套查询的内容,我意识到我的问题有一个解决方案。

db中的表名是test,这里是SQL格式的查询:

q = '''SELECT user_id, tweet_id, count(max_retweet) as count, 
                sum(max_retweet) as totat_retweet FROM 
                (SELECT tweet_id, max(cast(retweet as int)) as max_retweet, user_id FROM test
                GROUP BY user_id, tweet_id) 
            GROUP BY user_id
'''

所以在SQLAlchemy中等价转换的解决方案如下:

table = (
    select([
        func.max(test_db.columns.retweet).label('max_retweet'),
        test_db.columns.user_id,
        test_db.columns.tweet_id            
    ]).group_by(test_db.columns.user_id, test_db.columns.tweet_id)
    )

q = select([table.columns.user_id,
            table.columns.tweet_id,
            func.count(table.columns.max_retweet).label('count'),
            func.sum(table.columns.max_retweet).label('total_retweet')
             ])
q = q.group_by(table.columns.user_id)

但我想知道是否有distinct 表达式或distinct 的解决方案应该始终与count 一起使用,这就是我一直看到它使用的方法!

也感谢任何帮助或指导!

【讨论】:

请注意,tweet_id 最终会是不确定的。 你是绝对正确的。对于这个例子,我不关心tweet_id 的内容,我可以删除它。

以上是关于不同的 Group By 在 SQLAlchemy 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在 sqlalchemy 中使用 distinct()/group_by() 获取基于每个“名称”列的最新记录

SQLAlchemy的group_by和order_by的区别

SqlAlchemy group_by 并返回最大日期

将 SqlAlchemy group_by/func 查询转换为 GraphQL

四十三:数据库之SQLAlchemy之group_by和having子句

sqlAlchemy 按DateTime字段的年或月进行group_by查询