【问题标题】:Select first 50 rows then order选择前 50 行然后排序
【发布时间】:2017-08-16 21:57:55
【问题描述】:

是否可以使用select * from yellow_tripdata_staging fetch first 50 rows onlyafter 选择 Postgres 中的前 50 行,按列对结果进行排序?

如果有,怎么做?

编辑:表格真的很大,我得到哪些行并不重要。

这个问题是因为我使用 Redash 来可视化数据并且在排序结果上得到了一些奇怪的顺序。然后我意识到我用来排序的列不是数字而是 char,这会导致像 11 和 10 这样的值在 2 和 3 之前。

对不起这个愚蠢的问题

【问题讨论】:

  • 在 SQL 表或无序结果集中没有“前 50 行”之类的东西。您需要更具体地说明您想要完成的任务。
  • 哦,是的,就像您在“只是意味着根据当前物理顺序获取“前”50 行”中所说的那样,我忘记了这个问题

标签: sql postgresql sql-order-by sql-limit


【解决方案1】:

不完全清楚您的前 50 行是如何标识的以及它们应按什么顺序返回。关系数据库的表中没有“自然顺序”。如果没有明确的ORDER BY,则无法保证。

但是, 是您可以(ab-)使用的当前行的物理顺序。默认情况下,这是插入行的顺序 - 只要该表没有发生任何其他事情。但是RDBMS可以随时随意改变物理顺序,所以物理顺序是不可靠的。结果可以并且将会随着对表的写入操作而改变(包括VACUUM 或其他实用程序命令)。

我们称您的 用于在 50 行之后排序sort_col

(  -- parentheses required
TABLE yellow_tripdata_staging LIMIT 50
)
UNION ALL 
(  -- parentheses required
SELECT *
FROM  (TABLE yellow_tripdata_staging OFFSET 50) sub
ORDER  BY sort_col
);

更多解释(包括TABLE 和括号):

或者,假设sort_col被定义为NOT NULL

SELECT *
FROM   yellow_tripdata_staging
ORDER  BY CASE WHEN row_number() OVER () > 50 THEN sort_col END NULLS FIRST;

窗口函数row_number()允许出现在ORDER BY子句中。

row_number() OVER ()(带有空的OVER 子句)将根据行的当前物理顺序附加序列号 - 上述所有免责声明仍然适用。

CASE 表达式将前 50 个行号替换为 NULL,由于附加了 NULLS FIRST,它们排在第一位。实际上,前 50 行未排序,其余按 sort_col 排序。

或者,如果你的意思是按照sort_col取前50行,不排序,剩下的要排序:

SELECT *
FROM   yellow_tripdata_staging
ORDER  BY GREATEST (row_number() OVER (ORDER BY sort_col), 50);

或者,如果您只是想根据当前物理顺序或其他一些未公开(更可靠)的标准获取“前”50 行,您需要一个子查询或 CTE 对外部 SELECT 中的这 50 行进行排序:

SELECT *
FROM  (TABLE yellow_tripdata_staging LIMIT 50) sub
ORDER  BY sort_col;

您需要清楚地定义您的要求。

【讨论】:

    【解决方案2】:

    您可以按两列不同 列进行排序。例如:

    select yts.*
    from (select yts.*,
                 row_number() over (order by id) as seqnum
          from yellow_tripdata_staging yts
         ) yts
    order by (seqnum <= 50)::int desc,
             (case when seqnum <= 50 then id end),
             col
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 2018-07-24
      • 2012-10-26
      • 2017-07-28
      • 1970-01-01
      • 2012-03-26
      相关资源
      最近更新 更多