我在Postgres 9.4中有这个查询:
select id from question where id = any(
array_cat(
ARRAY[0,579489,579482,579453,561983,561990,562083]::integer[],
(select array(
select id from question where id not in
(0,579489,579482,579453,561983,561990,562083)
and status in (1, -1)
and created_at > 1426131436 order by id desc offset 0 limit 10 )
)::integer[]
)
)
它返回:
id
--------
561983
561990
562083
579453
579482
579489
580541
580542
580543
580544
580545
580546
580547
580548
580549
580550
(16 rows)
但它的顺序不正确。我需要根据子数组的结果排序结果:
array_cat(
ARRAY[0,579489,579482,579453,561983,561990,562083]::integer[],
(select array(
select id from question where id not in
(0,579489,579482,579453,561983,561990,562083)
and status in (1, -1)
and created_at > 1426131436 order by id desc offset 0 limit 10 )
)::integer[]
)
我该怎么做?
答案 0 :(得分:3)
基础:
由于您使用的是Postgres 9.4,因此您可以使用新的WITH ORDINALITY
:
WITH t AS (
SELECT *
FROM unnest('{0,579489,579482,579453,561983,561990,562083}'::int[])
WITH ORDINALITY AS t(id, rn)
)
(
SELECT id
FROM question
JOIN t USING (id)
ORDER BY t.rn
)
UNION ALL
(
SELECT id
FROM question
LEFT JOIN t USING (id)
WHERE t.id IS NULL
AND status IN (1, -1)
AND created_at > 1426131436
ORDER BY id DESC
LIMIT 10
);
由于您使用的是同一个数组两次,因此我使用CTE在查询前面添加 一次 。 unnest()
根据数组元素的顺序立即WITH ORDINALITY
获取行号(rn
。
不是将子查询填充到数组中并将其转换回来,而是直接使用它。便宜得多。排序顺序直接来自id
。
使用NOT IN
代替使用LEFT JOIN / IS NULL
从给定数组中排除ID(使用NULL值可能会很棘手):
只需使用UNION ALL
附加两个部分即可。括号必须在ORDER BY
查询的每一段都有单独的UNION ALL
:
最终JOIN
中的question
到SELECT
现在已经多余了,我将其剥离了。
答案 1 :(得分:0)
ORDER BY idx(your_array, your_element)
或
ORDER BY your_array # your_element
select id from question where id = any(
array_cat(
ARRAY[0,579489,579482,579453,561983,561990,562083]::integer[],
(select array(
select id from question where id not in
(0,579489,579482,579453,561983,561990,562083) and status in (1, -1)
and created_at > 1426131436 order by id desc offset 0 limit 10 )
)::integer[]
)
) ORDER BY array_cat(
ARRAY[0,579489,579482,579453,561983,561990,562083]::integer[],
(select array(
select id from question where id not in
(0,579489,579482,579453,561983,561990,562083) and status in (1, -1)
and created_at > 1426131436 order by id desc offset 0 limit 10 )
)::integer[]
) # id