SQL将多个相似的子查询压缩成单个子查询

标签 sql postgresql

你好,我的问题是关于优化 sql 查询。 以下查询很慢:

SELECT id, name,
, (SELECT rank_time FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1)::date AS rank_time
, (SELECT host_c    FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS host_c
, (SELECT index_pa  FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS index_pa
, (SELECT links_pa  FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS links_pa
, (SELECT index_pb  FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS index_pb
, (SELECT links_pb  FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS links_pb
FROM stage
ORDER BY name;

我认为这主要是因为从 stage_rank 中重复选择,是否可以让这个选择完成一次,并一次获得所有字段?

还有任何 postgresql 特定的功能在这里可能有帮助吗?

最佳答案

PostgreSQL中,您可以选择整条记录作为一个字段,稍后展开:

SELECT  id, name, (sr).*
FROM    (
        SELECT  id, name,
                (
                SELECT  stage_rank
                FROM    stage_rank
                WHERE   stage = stage.id
                ORDER BY
                        rank_time DESC
                LIMIT 1
                ) sr
        FROM    stage
        ) q
ORDER BY
        name

或重写查询:

SELECT  DISTINCT ON (s.name, s.id, sr.rank_time, sr.id)
        s.id, s.name, sr.*
FROM    stage s
JOIN    stage_rank sr
ON      sr.stage = s.id
ORDER BY
        s.name, s.id, sr.rank_time DESC, sr.id DESC

或者换一种方式重写:

SELECT  id, name, (sr).*
FROM    (
        SELECT  s.id, s.name, sr, ROW_NUMBER() OVER (PARTITION BY s.id ORDER BY sr.rank_time DESC, sr.id DESC) rn
        FROM    stage
        JOIN    stage_rank sr
        ON      sr.stage = s.id
        ) q
WHERE   rn = 1
ORDER BY
        name

关于SQL将多个相似的子查询压缩成单个子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10651330/

相关文章:

sql - PostgreSQL:选择具有特定成员的组

java - 使用什么算法或模式来检查哪些表中的哪些行将在 mysql/pgsql 中级联删除?

mysql - SQL查询-如果存在则更新,否则插入

c# - Lambda 表达式 LINQ 等同于 SQL Exists Query on Same Table/Variable

mysql - 更新整个表而不迭代 ID

PostgreSQL:删除列并重新创建相关 View

sql - 列的默认值(当值设置为 NULL 时)等于其他列

mysql - 如何连接两个表mysql?

sql - 通过存储过程将 stringify serializeArray 存储在 SQL Server 数据库中

debugging - 如何获取 Postgres 中某些信号(例如 SIGINT)的处理程序名称/地址?