Python 让PostgreSQL尊重输入参数的顺序?
这个问题有点历史性—— 我不熟悉构建专门的查询,所以我假设如果我在SELECT查询中提供IN子句,它将以相同的顺序返回结果。不幸的是,情况并非如此Python 让PostgreSQL尊重输入参数的顺序?,python,postgresql,Python,Postgresql,这个问题有点历史性—— 我不熟悉构建专门的查询,所以我假设如果我在SELECT查询中提供IN子句,它将以相同的顺序返回结果。不幸的是,情况并非如此 SELECT * FROM artists WHERE id IN (8, 1, 2, 15, 14, 3, 13, 31, 16, 5, 4, 7, 32, 9, 37) >>> [7, 32, 3, 8, 4, 2, 31, 9, 37, 13, 16, 1, 5, 15, 14] 没有包括我使用Python循环结果并将ID附
SELECT * FROM artists WHERE id IN (8, 1, 2, 15, 14, 3, 13, 31, 16, 5, 4, 7, 32, 9, 37)
>>> [7, 32, 3, 8, 4, 2, 31, 9, 37, 13, 16, 1, 5, 15, 14]
没有包括我使用Python循环结果并将ID附加到列表中的步骤
所以问题是,有没有一种方法可以让Postgre以相同的顺序返回结果,从而尊重in子句中给出的参数的顺序?除非指定order by子句,否则查询结果将以不确定的顺序返回 如果您确实希望以请求的方式执行查询,那么可以构造这样一个子句。下面是一个使用部分数据的示例
create table artists (
id integer not null primary key,
name char(1) not null);
insert into artists
values
(8, 'a'),
(1, 'b'),
(2, 'c'),
(15, 'd'),
(14, 'e'),
(3, 'f'),
(13, 'g');
select *
from artists
where id in (8, 1, 2, 15, 14, 3, 13)
order by
id = 8 desc,
id = 1 desc,
id = 2 desc,
id = 15 desc,
id = 14 desc,
id = 3 desc,
id = 13 desc;
基于这一点和你的另一个问题,我认为你的模型或你尝试这样做的方式有问题。也许你应该发布一个关于如何做你想做的事情的更一般的问题
如果你有艺术家和排名表,你应该能够通过你的ORM做类似的事情
select
a.*
from
artists a,
rankings r
where
a.id = r.artist_id
order by
r.score desc;
我建议您让PostGreSQL以任意顺序返回集合,特别是因为很难从Django接口执行细粒度SQL级别控制,然后在Python中按您希望的方式对其排序-theresultset.sortkey=yourlistofids.index如果ResultSet是由数据库生成的任意顺序列表,而yourlistofids是您希望保留其顺序的列表,则应该可以进行排序。另一种方式:
SELECT *
FROM artists
WHERE id IN (8, 1, 2, 15, 14, 3, 13, 31, 16, 5, 4, 7, 32, 9, 37)
ORDER BY POSITION(id::text in '(8, 1, 2, 15, 14, 3, 13, 31, 16, 5, 4, 7, 32, 9, 37)');
谢谢你的回答。我确实遗漏了很多关于我的应用程序是如何工作的。长话短说,排名不仅对应于艺术家,还可以对应于我们给出的任何数量的对象类型。也就是说,我正在使用Django的泛型来创建那些关系,这使得我在这里尝试做的事情变得有点困难。非常遗憾的是,博士后无法保持秩序。这也会让我免于很多麻烦!我的情况与此类似,排序顺序每分钟更改几次,因此我在我的应用程序中进行排序,以防止完全不必要的数据库写入。因此,订购不是一种选择,在另一种情况下,我希望我能接受这两种答案非常感谢你,我个人会选择这条路线,但是为了人们在谷歌上找到这个问题的兴趣,我会接受cope的答案。FWIW,我建议反对这个解决方案。数据库设计用于排序,而应用程序语言则不是。这比让数据库排序要慢得多。@理论上,Python在排序适合内存的数据方面非常出色——它的timsort算法非常出色,在Java世界中也吸引了很多注意力。你说Python不是设计用来做排序的,而它却做得很好,这是荒谬的。position函数决定了一个字符串在另一个字符串中的位置。这将无法正常工作,因为并非所有ID的位数都相同。假设你想让id 14成为第一个。您可能会以id 1为第一个结束。或id 4。