如何将 MySQL 转换为 PostgreSQL 并添加时区转换

如何解决如何将 MySQL 转换为 PostgreSQL 并添加时区转换

我想显示过去 2 年内访问过的所有课程、上次访问者和访问时间。

此 MySQL 查询列出了上次访问每个课程的时间和访问者。我正在将此查询转换为 PostgreSQL 9.3.22。我对 Postgres 的接触并不多,事实证明这非常困难。我还需要将纪元日期转换为不同的时区,因为 PostgreSQL 数据库位置不在我的时区中。编辑:timecreated 在两个数据库中都存储为纪元(例如 1612399773

select
    userid 'lastaccesseduserid',courseid,contextid,from_unixtime(max(timecreated),'%D %M %Y') 'lastaccesseddate'
from mdl_logstore_standard_log
where timecreated >= unix_timestamp(date_sub(now(),interval 2 year))
group by courseid

这列出了这样的输出:

| lastaccesseduserid | courseid | contextid | lastaccesseddate  |
|--------------------|----------|-----------|-------------------|
| 45                 | 6581     | 68435     | 22nd January 2021 |
| 256676             | 32       | 4664      | 19th August 2019  |
etc.

我在转换为 PostgreSQL 方面所做的努力:

select
    distinct ON (courseid) courseid,to_timestamp(max(timecreated))::timestamptz::date at time zone 'utc' at time zone 'Australia/Sydney' "last accessed date",userid
from mdl_logstore_standard_log
where timecreated >= extract(epoch from now()- interval '2 year')
group by courseid
-- error: column userid,contextid must appear in the GROUP BY clause or be used in an aggregate function

这些列都不是主键(id 是,根据 here)。按 id 分组是不好的,因为它将列出日志表中的每个条目。任何帮助表示赞赏!

解决方法

Postgres 是正确的,该查询不是有效的 SQL。

SQL-92 及更早版本不允许查询的选择列表、HAVING 条件或 ORDER BY 列表引用未在 GROUP BY 子句中命名的非聚合列。

您不能使用 group by courseidselect courseid,contextid,userid,因为每个 courseid 可能有许多具有不同上下文 ID 和用户 ID 的行。您要么需要 group by courseid,userid,要么需要 tell the database how you want those columns aggregated 喜欢 sumstring_agg

我不能告诉你哪个是正确的,但原来的从来没有真正奏效。 MySQL 只是为您随机选择一个值。

在这种情况下,服务器可以自由地从每个组中选择任何值,因此除非它们相同,否则选择的值是不确定的,这可能不是您想要的

MySQL 允许一些不明智的 SQL“扩展”,后来的版本默认将它们关闭。这个特殊的由 ONLY_FULL_GROUP_BY 控制,默认情况下 MySQL 5.7 及更高版本明智地打开。您的数据库要么将其关闭,要么太旧以至于它不是默认设置。

请参阅 MySQL Handling of GROUP BY 了解更多信息。

我建议首先启用 ONLY_FULL_GROUP_BY 并修复 MySQL 中的查询。然后移植到 Postgres。

MySQL 有很多这样的非标准特性。 PostgreSQL 更符合标准。转换为标准 SQL 和 PostgreSQL 将是一场斗争。我建议一次做一个。首先,通过打开 ANSI and TRADITITONAL SQL modes 转换为标准 SQL 并修复 MySQL 中产生的问题。然后尝试将现在更标准的 SQL 转换为 PostgreSQL。这些 SQL 模式是 MySQL 服务器配置的集合,例如 ONLY_FULL_GROUP_BY,并且可以一次打开和修复一个。


请注意,PostgreSQL 9.3.22 已于两年前停产。做所有这些工作来更改数据库只是为了使用过时的版本是愚蠢的。考虑升级。

将时间存储为 Unix 纪元既尴尬又不必要。如果可能,请考虑在迁移数据时转换为 timestamp。如果您还打算存储时区,请使用 timestamp with zone

,

您没有说明您的意图,但您似乎想获取每个课程 ID 的最新 timecreated

这在 Postgres 中不需要 GROUP BY,只需要 distinct on ()。其额外好处是您可以包含所需的任何列,而不受 GROUP BY 规则的限制。但是,这仅适用于每个 courseid 需要一行(并且应该是“最早的”或“最新的”)。对于其他要求(例如“三个最新”),窗口函数更适合。

to_timestamp() 已经返回一个 timestamptz,因此不需要强制转换。如果您想删除时间部分(这是 ::date 演员将要做的),我认为应该在您调整时区后完成。但是如果你不关心时间,那么调整时区似乎是徒劳的。

select distinct ON (courseid) 
        courseid,to_timestamp(timecreated) at time zone 'utc' at time zone 'Australia/Sydney' "last accessed date",userid
from mdl_logstore_standard_log
where to_timestamp(timecreated) >= current_timestamp - interval '2 year'
group by courseid,3 DESC

您还应该在 WHERE 子句中使用实际的 timestamp 值,因为“2 年”的持续时间可能因实际年份而异。比较时代不会考虑到这一点。

从长远来看,您可能需要考虑将列完全更改为正确的 timestamptz 列。

您也可以重复整个表达式,而不是在 order by 中引用 (3) 中的列索引:order by courseid,to_timestamp(timecreated) at time zone 'utc' at time zone 'Australia/Sydney' DESC


而且您真的不应该使用 Postgres 9.3 - 尤其不应该用于新安装。没有理由不使用最新版本(截至 2021-02-04 为 13)。如果这是现有(旧)安装,请尽快升级。 Upgrading from 9.3.22 to 13.1 gives you 2.7 years worth of fixes (2278 of them)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res