PostgreSQL:SELECT DISTINCT ON 表达式必须与初始 ORDER BY 表达式匹配

2024-02-03

假设我有以下 PostgreSQL 表,名为products:

CREATE TABLE IF NOT EXISTS mytable (
    id serial NOT NULL PRIMARY KEY,
    label VARCHAR(50) NOT NULL,
    info jsonb NOT NULL,
    created_at timestamp NOT NULL DEFAULT now()
);

这是一些测试数据。请注意,我的实际表有数百万条记录。

INSERT INTO products (label, info) VALUES ('a', '[1, 2, 3]');
INSERT INTO products (label, info) VALUES ('a', '[1, 2, 3]');
INSERT INTO products (label, info) VALUES ('c', '[1, 2, 3]');
INSERT INTO products (label, info) VALUES ('c', '[1, 2, 3]');
INSERT INTO products (label, info) VALUES ('b', '[1, 2, 3]');

我想编写一个查询来获取不同的标签并按以下顺序对记录进行排序created_at场地。我的第一反应是编写以下查询:

SELECT DISTINCT ON (label) * FROM products ORDER BY created_at DESC;

但是,此操作失败并出现以下错误:

错误:SELECT DISTINCT ON 表达式必须与初始 ORDER BY 表达式匹配

看起来我可以使用 SQL 子查询来解决这个问题:

SELECT * FROM (
    SELECT DISTINCT ON (label) * FROM products
) AS subquery ORDER BY created_at DESC;

生成以下预期结果:

 id | label |   info    |         created_at
----+-------+-----------+----------------------------
  5 | b     | [1, 2, 3] | 2022-11-14 03:32:23.245669
  3 | c     | [1, 2, 3] | 2022-11-14 03:32:23.242813
  1 | a     | [1, 2, 3] | 2022-11-14 03:32:23.239791

这是解决此问题的最佳方法吗?或者有没有更快的方法来查询这些数据?请注意,我在上面提到了我的实际表如何拥有数百万条记录,因此我想提出尽可能最佳的查询。


Leading ORDER BY表达式必须匹配DISTINCT ON表达式(反之亦然):


SELECT DISTINCT ON (label) * FROM products ORDER BY label, created_at DESC;  

See:

  • 选择每个 GROUP BY 组中的第一行? https://stackoverflow.com/questions/3800551/select-first-row-in-each-group-by-group/7630564#7630564

不清楚你是否想要created_at ASC or created_at DESC:您显示了后者,但您称为“预期”的结果与前者匹配 - 因为您的“修复”并没有像您认为的那样进行。

对结果(不同)行进行排序created_at DESC,你必须运行一个外部SELECT使用不同的排序顺序:

SELECT *
FROM  (
   SELECT DISTINCT ON (label) *
   FROM   products
   ORDER  BY label, created_at DESC
   ) sub
ORDER  BY created_at DESC;

See:

  • PostgreSQL DISTINCT ON 具有不同的 ORDER BY https://stackoverflow.com/questions/9795660/postgresql-distinct-on-with-different-order-by/9796104#9796104

对于大表,一定要有索引(label, created_at) or (label, created_at DESC), 分别。

我的实际表有数百万条记录,所以我想提出尽可能最好的查询。

根据未公开的细节,可能会有(更快)更快的解决方案。最重要的是:

  • 总共有多少行有多少个不同的“标签”?
  • 是否有一个单独的表,每个(相关)不同标签一行?
  • 你真的需要吗SELECT *, or is SELECT label, created_at一切你需要的?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PostgreSQL:SELECT DISTINCT ON 表达式必须与初始 ORDER BY 表达式匹配 的相关文章

  • 如何在 DataColumn.Expression 中使用 IF/ELSE 或 CASE?

    我有一个包含 1 列的表 状态 我想添加另一列名为 Action 的列 其值如下 如果 Status Yes 则 Action Go 否则 Action Stop 我使用以下代码添加到 操作 列中 但它不起作用 myDataTable Co
  • 提高 PostgreSQL 1 亿数据左连接查询性能

    我在用Postgresql 9 2 version Windows 7 64 bit RAM 6GB 这是一个Java企业项目 我必须在我的页面中显示订单相关信息 有三个表通过左连接连接在一起 Tables TV HD 389772 行 T
  • Postgres 中 -Infinity 和 Infinity 的适当值

    在一种情况下 我们必须在 Postgres DB 中存储 无穷大和 无穷大的值 应该考虑什么合适的值 如果没有 请建议最合适的替代方案 你实际上可以使用 infinity and infinity for FLOAT4 and FLOAT8
  • PostgreSQL 仅当列存在时才重命名该列

    我在中找不到PostgreSQL 文档 https www postgresql org docs 12 sql altertable html如果有办法运行 ALTER TABLE tablename RENAME COLUMN IF E
  • JDBC 时间戳和日期 GMT 问题

    我有一个 JDBC 日期列 如果我使用 getDate 则会得到 date 仅部分2009 年 10 月 2 日但如果我使用 getTimestamp 我会得到完整的 date 2009 年 10 月 2 日 13 56 78 890 这正
  • 如何在Oracle中从表中选择列,*?

    我正在创建很多脚本 有时为了检查表是否根据我的需要进行更新 我会即时编写几个 SELECT 语句 在 SQL SERVER 中你可以这样写 SELECT Column1 FROM MY TABLE 出于可见性原因 这很有用 但是这似乎在 O
  • 每行中非空列的计数

    我有一个包含 4 列的表 在第 5 列中我想存储前 4 列中有多少个非空列的计数 例如 其中 X 是任意值 Column1 Column2 Column3 Column4 Count X X NULL X 3 NULL NULL X X 2
  • 如何根据条件删除结果以计算平均值

    我有下面的架构 对其的快速解释是 鲍勃评分为 5 5 詹姆斯评分 1 5 梅西百货评分高达 5 5 逻辑 如果我是 A 请查找我屏蔽的所有人 查阅所有电影评论 任何留下电影评论且 personA 已屏蔽的人 请将其从计算中删除 计算电影的平
  • 从 json 数组获取值并执行 sql 插入

    这是我的数组 json 1 Device ID a9a3346be4375a92 Date 2012 05 31 Time 15 22 59 Latitude 51 4972912 Longitude 0 1108178 2 Device
  • 我应该定义索引(A)和索引(B),还是索引(A,B),或者两者都定义?

    在我的表中 我有两个密切相关的列 A 和 B 我应该考虑哪些因素来决定是否创建 索引 A 和索引 B 索引 A B 以上两者 如果我 仅使用类似的查询where A 5 and B 10 并且从不喜欢where A 5 也可以使用类似的查询
  • 在 azure Devops 管道中部署 SQL 时遇到错误

    我在 azure Devops 的发布管道中使用 sql DACPAC 类型的部署 但出现以下错误 我对 SQL 不了解 有什么建议吗 Publishing to database database name on server Serve
  • 验证 sql/oracle 中的电子邮件/邮政编码字段

    对于以下方面的一些建议将不胜感激 是否可以通过 oracle 中的 sql 中的某种检查约束来验证电子邮件和邮政编码字段 或者我怀疑 pl sql 带有正则表达式的这种事情 Thanks 这是电子邮件地址的正则表达式语法 包括引号 a zA
  • 在 docker 中将 pgadmin 连接到 postgres

    我有一个docker compose与服务文件python nginx postgres and pgadmin services postgres image postgres 9 6 env file env volumes postg
  • Oracle如何将UTC时间转换为本地时间(缺少偏移信息)

    我有一个包含日期列的表 我认为该列中的日期是以 UTC 格式保存的 我希望检索日期时以当地时间打印 这意味着当我从德国调用日期时 结果应该是这样的 2015 04 29 11 24 06 0200UTC EUROPE BERLIN 我尝试了
  • 优化 LATERAL join 中的慢速聚合

    在我的 PostgreSQL 9 6 2 数据库中 我有一个查询 该查询根据一些股票数据构建计算字段表 它为表中的每一行计算 1 到 10 年的移动平均窗口 并将其用于周期性调整 具体来说 CAPE CAPB CAPC CAPS 和 CAP
  • Postgres < 9.0 的 DO 块相当于什么

    Postgres 8 4 8 相当于什么 DO BEGIN IF NOT EXISTS THEN EXECUTE END IF END create function f returns void as BEGIN IF NOT EXIST
  • 与 SQL 中的 IN 运算符相反

    我怎么能做相反的事情 换句话说 选择所有姓氏不是 Hansen 或 Pettersen 的人 WHERE lastname NOT IN Hansen Pettersen 请参阅 IN 和 NOT IN 运算符 部分SQLite 所理解的
  • 如何将彼此“接近”的纬度/经度点分组?

    我有一个用户提交的纬度 经度点的数据库 并且正在尝试将 接近 点分组在一起 接近 是相对的 但目前看来约为 500 英尺 起初 我似乎只能按前 3 个小数位具有相同纬度 经度的行进行分组 大约是一个 300x300 的盒子 了解当您远离赤道
  • SQL Server Like 查询不区分大小写

    Query SELECT from Table 2 WHERE name like Joe Output 1 100 Joe 2 200 JOE 3 300 jOE 4 400 joe 为什么不区分大小写 Problem 查询不区分大小写
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced

随机推荐