使PostgreSQL尊重输入参数的顺序?

时间:2010-02-12 23:44:13

标签: python postgresql

这个问题有一点历史 - Is there a way to make a query respect the order of the inputted parameters?

我是构建“专业”查询的新手,所以我假设如果我在IN查询中提供SELECT子句,它将以相同的顺序返回结果。不幸的是,事实并非如此。

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附加到列表的步骤。)

所以问题是,有没有办法让Postgres尊重IN子句中给出的参数的顺序,方法是返回相同顺序的结果?

3 个答案:

答案 0 :(得分:5)

除非您指定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;

答案 1 :(得分:2)

我建议你让PostGreSQL以任意顺序返回集合(特别是因为很难从Django接口进行细粒度的SQL级控制),然后按照你希望的方式对它进行排序 Python - theresultset.sort(key=yourlistofids.index)应该没问题(当theresultset是数据库产生的任意顺序列表时,yourlistofids是要保留其顺序的列表。

答案 2 :(得分:-1)

另一种方式:

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)');