【发布时间】:2018-10-17 14:09:07
【问题描述】:
我有一张这样的表:
+--------+-------------+----------+---------+
| PK(id) | FK(user_id) | ctime | comment |
+--------+-------------+----------+---------+
| 1 | 1 | 20170101 | "Haha" |
+--------+-------------+----------+---------+
| 2 | 2 | 20170102 | "Nope" |
+--------+-------------+----------+---------+
| 3 | 2 | 20170104 | "Geez" |
+--------+-------------+----------+---------+
| 4 | 1 | 20170110 | "Gone" |
+--------+-------------+----------+---------+
我希望检索每个FK(user_id) 的最新记录,如下所示:
+--------+-------------+----------+---------+
| PK(id) | FK(user_id) | ctime | comment |
+--------+-------------+----------+---------+
| 3 | 2 | 20170104 | "Geez" |
+--------+-------------+----------+---------+
| 4 | 1 | 20170110 | "Gone" |
+--------+-------------+----------+---------+
所以我尝试了SELECT DISTINCT T.* FROM my_table AS T
和SELECT DISTINCT T.user_id FROM my_table AS T;
但是,它们不起作用!
我尝试了 GROUP BY 语句,如下所示,
SELECT T.* FROM my_table AS T GROUP BY `user_id` DESC
它确实像我期望的那样完美。 于是我开始想办法把SQL翻译成Django!
首先,我尝试使用 RawSQL:
from django.db.models.expressions import RawSQL
def _select_latest_rows(model_class, target_column_name, query_set=None):
query_set = query_set or model_class.objects
table_name = model_class._meta.db_table
raw_sql = '''
SELECT * FROM %s GROUP BY %s
'''
return query_set.annotate(val=RawSQL(raw_sql, (table_name, target_column_name,)))
每当我调用此函数时,Django 都会弹出以下错误。
django.db.utils.ProgrammingError: (1064, "You have an error in your SQL syntax
blah blah blah...
然后我检查了我的查询字符串:
print(_select_latest_rows(model_class, target_column_name, query_set).query)
然后它返回:
SELECT T.`id`, T.`user_id`, T.`ctime`, T.`comment`, (SELECT * FROM my_table GROUP BY user_id) AS `val` FROM my_table
好吧,我不得不说我对 SQL 语法不太熟悉,到目前为止,我还没有弄清楚这个查询字符串中错误的位置:(
我必须按照this answer 中的建议在模型的管理器实例中调用raw() 函数吗?
model_class.objects.raw('SELECT T.* FROM my_table AS T GROUP BY `user_id` DESC LIMIT 10 OFFSET 0')
或者我不应该在开头使用 GROUP BY 语句?
【问题讨论】:
-
有一个
GOUP_BY的模块 - github.com/kako-nawao/django-group-by 可能会有帮助。