sql - 如何按照数组元素的顺序对查询结果进行排序?

标签 sql postgresql sql-order-by set-returning-functions unnest

我在 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[]
    )

我该怎么做?

最佳答案

基础知识:

由于您使用的是 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
);

解释

  1. 由于您两次使用同一个数组,我在查询前添加了一个 CTE,您可以在其中提供数组一次unnest() 它立即WITH ORDINALITY 根据数组元素的顺序获取行号 (rn)。

  2. 与其将子查询填充到数组中再将其转换回来,不如直接使用它。便宜得多。排序顺序直接从 id 派生。

  3. 不要使用 NOT IN 从给定数组中排除 ID(这对于 NULL 值可能很棘手)使用 LEFT JOIN/IS NULL:

  4. 只需将这两部分附加到UNION ALL。括号需要在 UNION ALL 查询的每条腿上有单独的 ORDER BY:

  5. 最后的 SELECTJOINquestion 现在是多余的,我将其删除。

    <

关于sql - 如何按照数组元素的顺序对查询结果进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29574203/

相关文章:

sql - 使用 DB2 计算 select 子句中的行数

sql - ESQL - 有谁知道可以为 ESQL 提供静态代码分析的工具吗?

ruby-on-rails - 即使密码错误,我也可以访问 Rails 上的 postgres 数据库

performance - Postgres函数优化

mysql - 如何按每列不同优先级的多列排序?

MySQL 按连接中的字段值排序一次,然后按非连接列排序

mysql - 增量变量和存储过程检查重复项的问题

sql - 如何使用 SQL 或 Toad 提取表定义

php - 为什么 Laravel 调用 execute() 会返回重复的结果?

Mysql group by冲突记录与order by