将 SELECT DISTINCT ON 查询从 Postgresql 转换为 MySQL

2024-04-17

我一直在使用PostgreSQL现在迁移到MySQL.

在我的查询中,我正在使用PostgreSQL's SELECT DISTINCT ON (col1, col2, col3),我想知道这句话是否有对应的内容MySQL.


没有完全等效的方法可以将使用 SELECT DISTINCT ON 的 Postgresql 查询转换为 MySQL。

Postgresql SELECT DISTINCT ON

在 Postgresql 中,以下查询将消除表达式所在的所有行(col1, col2, col3)匹配,并且它只会为每组匹配的行保留“第一个 col4,col5 行”:

SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename

所以如果你的表是这样的:

col1 | col2 | col3 | col4 | col5
--------------------------------
1    | 2    | 3    | 777  | 888
1    | 2    | 3    | 888  | 999
3    | 3    | 3    | 555  | 555

我们的查询将仅保留 (1,2,3) 的一行和 (3,3,3) 的一行。结果行将是:

col4 | col5
-----------
777  | 888
555  | 555

请注意,每个集合的“第一行”是不可预测的,除非我们指定 ORDER BY,否则我们的第一行也可能是 (888, 999):

SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4

(表达式上的 DISTINCT 必须与最左边的 ORDER BY 表达式匹配,但 ORDER BY 可以包含其他表达式)。

MySQL 对 GROUP BY 的扩展

MySQL 扩展了使用GROUP BY http://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html这样我们就可以选择 GROUP BY 子句中未命名的非聚合列。每当我们选择非聚合列时,服务器都可以自由地从该列的每个组中选择任何值,因此结果值将是不确定的。

所以这个 Postgresql 查询:

SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename

可以被认为等同于这个 MySQL 查询:

SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3

Postgresql 和 MySQL 都会为每个(col1、col2、col3)返回“第一行”,并且在这两种情况下,返回的行都是不可预测的,因为我们没有指定和 order by 子句。

很多人很想用 ORDER BY 转换这个 Postgresql 查询:

SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4

与这个:

SELECT col4, col5
FROM (
  SELECT col1, col2, col3, col4, col5
  FROM tablename
  ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3

这里的想法是将 ORDER BY 应用于子查询,以便当 MySQL 按 col1、col2、col3 分组时,它将保留第一个遇到的 col4 和 col5 值。这个想法是好的,但却是错误的!MySQL可以自由地为col4和col5选择任何值,并且我们不知道哪个是第一个遇到的值,这取决于优化器。所以我将其更正为:

SELECT t1.col4, t1.col5
FROM tablename t1 INNER JOIN (SELECT col1, col2, col3, MIN(col4) as m_col4
                              FROM tablename
                              GROUP BY col1, col2, col3) s
     ON t1.col1=s.col1
        AND t1.col2=s.col2
        AND t1.col3=s.col3
        AND t1.col4=s.m_col4
GROUP BY
  t1.col1, t1.col2, t1.col3, t1.col4

但这开始变得更加复杂。

结论

作为一般规则,没有一种确切的方法将 Postgresql 查询转换为 MySQL 查询,但有很多解决方法,结果查询可能与原始查询一样简单,也可能变得非常复杂,但这取决于查询本身。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 SELECT DISTINCT ON 查询从 Postgresql 转换为 MySQL 的相关文章

  • Gorm 总是返回带有 nil 值的结构

    我正在使用 Gorm 构建 Go Web API 作为 Amazon RDS 中 Postgresql 数据库的 ORM 问题是 Gorm 总是返回一片结构 其值全部为零 尽管数据库已经填充了数据 切片中的结构体数量是否合适取决于LIMIT
  • 无法安装 psycopg2 (pip install psycopg2)

    我使用的是 MAC 和 python 版本 2 7 14 Collecting psycopg2 Could not fetch URL https pypi python org simple psycopg2 There was a p
  • 在 MacOSX10.6 上运行 python 服务器时 MySQLdb 错误

    运行我的服务器 python manage py runserver 产生以下错误 django core exceptions ImproperlyConfigured 加载 MySQLdb 模块时出错 没有名为 MySQLdb 的模块
  • 社交应用程序的数据库设计和优化注意事项

    通常的情况 我有一个简单的应用程序 允许人们上传照片并关注其他人 因此 每个用户都会有类似 墙 或 活动源 的东西 他或她可以在其中看到他 她的朋友 他或她关注的人 上传的最新照片 大多数功能都很容易实现 然而 当涉及到这个历史活动源时 由
  • 数据库错误:值对于类型字符变化来说太长(100)

    我有一个 Django 网站 运行我们几年前在内部构建的迷你 CMS 它使用 postgresql 保存简单的标题和一段文本时 出现以下错误 value too long for type character varying 100 奇怪的
  • 比较表中的行以了解字段之间的差异

    我有一个包含 20 多列的表 客户端 其中大部分是历史数据 就像是 id clientID field1 field2 etc updateDate 如果我的数据如下所示 10 12 A A 2009 03 01 11 12 A B 200
  • 如何在 phpmyadmin 中创建 MySQL 触发器

    我想在 MySQL 中创建一个触发器 我运行以下命令 mysql gt delimiter mysql gt CREATE TRIGGER before insert money BEFORE INSERT ON money gt FOR
  • Postgres jsonb数组:查询非空交集

    假设我有一个名为的 JSONB 列value在表中t 这些 JSON 的内部是tags字段是字符串列表 我想对这些标记的 JSON blob 进行查询 foo or bar 所以假设表数据如下所示 value tags other tags
  • 使用 MS Access 获取行的第一个实例

    EDITED 我有这个查询 我想SELECT表中记录的第一个实例petTable SELECT id pet ID FIRST petName First Description FROM petTable GROUP BY pet ID
  • MYSQL - 查找最近的前一天

    我可以以某种方式 不使用 PHP 找到一周中最近的前一天日期吗 Like 最近的上一个星期二的日期是哪一天 CURDATE INTERVAL WEEKDAY CURDATE wday IF WEEKDAY CURDATE gt wday 0
  • mysql-如何向列申请补助?

    用户名 撤销对数据库的选择 Person I set GRANT SELECT id ON database Person TO username localhost 不是工作 gt SELECT secret FROM Person Go
  • 如何使用 MySQL 的 LOAD DATA LOCAL INFILE 在导入 CSV 时将字符串日期更改为 MySQL 日期格式

    我正在使用 MySQL 的 LOAD DATA LOCAL INFILE SQL 语句将数据从 CSV 文件加载到现有数据库表中 下面是一个 SQL 语句示例 LOAD DATA LOCAL INFILE file csv INTO TAB
  • 当sql连接中存在两个同名列时,如何从一个表列中获取值

    当我连接两个具有相同名称列的表时 我目前面临着尝试获取值的问题 例如 table1 date和table2 date 每个表中的日期不同 我将如何获取 日期 本例中的表1 我目前正在跑步 while row mysqliquery gt f
  • 阻止注销页面后的后退按钮

    我有 php 注销页面 当用户单击注销链接时 请参阅此页面并重定向到索引页面 但是当单击后退按钮时 我会看到带有用户数据的上一页 当然 当我刷新页面时 我看不到以前的页面和数据 我在单击注销并单击后退按钮后检查了其他代码 drupal 但我
  • 如何使用 typeorm 在 postgres 中保存 json 对象数组

    我正在尝试在 postgres 中保存 jsonb 类型的对象数组 Entity Column type jsonb array true nullable true testJson object 我在邮递员中发送的json testJs
  • 为什么我的 if 语句没有按我预期的方式工作?

    我正在尝试实现以下目标 我向我的 SQL 数据库询问使用SELECT FROM subjects 这样做之后我要求使用数组mysqli fetch assoc 在那之前一切都很好 现在的问题是 当我尝试在每个循环中修改 genero 的值
  • 如何在Sequelize中设置查询超时?

    我想看看如何在 Sequelize 中设置查询的超时时间 我查看了 Sequelize 文档以获取一些信息 但我找不到我要找的东西 我发现的最接近的是 pools acquire 选项 但我不想设置传入连接的超时 而是设置正在进行的查询的超
  • MySQL PHP邮政编码比较具体距离

    我试图找出比较一个邮政编码 用户提供的 和一大堆其他邮政编码 现在大约有 200 个邮政编码 之间的距离的最有效方法 相对于加载时间 但它会随着时间的推移而增加 我不需要任何精确的东西 只是在球场上 我下载了整个美国的邮政编码 csv 文件
  • 在 PostgreSQL 中使用月份名称排序

    我有一个表 其中有一个字段 Month Name 它包含月份的名称 我想按月份名称排序 不是按字母顺序 而是按实际顺序 例如一月 二月等 如何使用 PostgreSQL 实现此操作 有什么方法可以将月份名称转换为其数值吗 id billed
  • MySQL 按重复项从上到下排序

    我有一个lammer问题 因为我不是mysql专业人士 我有类似的字段 id color 1 red 2 green 3 yellow 4 green 5 green 6 red 我想按重复项进行分组 最常见的重复项先进行分组 所以应该这样

随机推荐