我定义了一个函数来总是给我下一个星期天的日期。它工作正常,这是代码:
CREATE FUNCTION nextSunday() RETURNS date AS $$
DECLARE
dia_semana INT := CAST(EXTRACT(DOW FROM CURRENT_DATE)as INT);
dia INT := 7 - dia_semana;
BEGIN
RETURN current_date + dia;
END;
$$ LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)
我有另一个函数可以将数据转储到文件中,我需要在nextSunday()里面使用函数:
CREATE OR REPLACE FUNCTION popularTabelaPessoa() RETURNS VOID AS $$
BEGIN
COPY(SELECT pe.id, pe.fk_naturalidade, pe.fk_documentacao_pessoal, pe.nome,
pe.cpf, pe.data_nascimento, pe.sexo, pe.estado_civil, pe.nome_mae,
pe.data_alteracao, pe.usuario_banco_alteracao,
pe.usuario_aplicacao_alteracao
FROM fluxo_lt.banca ba
INNER JOIN corporativo.localidade lo
ON ba.fk_municipio = lo.id
INNER JOIN fluxo_lt.agendamento_candidato ac
ON ac.fk_banca = ba.id
INNER JOIN info_detran.processo as …Run Code Online (Sandbox Code Playgroud) 我试图从postgres中的查询中提取日期.时间戳存储为UTC,所以如果我有1/1/2014 02:00:00,我希望太平洋时间的日期是12/31/2013,而不是2014年1月1日.我非常接近,但查询2和3仍然返回2014年1月1日.
SELECT '1-1-2014 02:00:00'::timestamp at time zone 'America/Los_Angeles';
Run Code Online (Sandbox Code Playgroud)
回报
2014-01-01 02:00:00-08
Run Code Online (Sandbox Code Playgroud)
-
SELECT CAST('1-1-2014 02:00:00'::timestamp at time zone 'America/Los_Angeles' AS Date);
Run Code Online (Sandbox Code Playgroud)
回报
2014-01-01
Run Code Online (Sandbox Code Playgroud)
但是我希望它能够回归2013-12-31.
SELECT CAST('1-1-2014 00:02:00'::timestamp at time zone 'America/Los_Angeles' AS Date) at time zone 'America/Los_Angeles';
Run Code Online (Sandbox Code Playgroud)
回报
2014-01-01 00:00:00
Run Code Online (Sandbox Code Playgroud)
但是我希望它能够回归 2013-12-31 00:00:00
我基本上想要在它所在的时区中返回日期,在这种情况下是太平洋时区.
我只是花了一个小时绝望,这两个表达式的结果有差异:
db=# SELECT '2012-01-18 1:0 CET'::timestamptz AT TIME ZONE 'UTC'
,'2012-01-18 1:0 Europe/Vienna'::timestamptz AT TIME ZONE 'UTC';
timezone | timezone
---------------------+---------------------
2012-08-18 00:00:00 | 2012-08-17 23:00:00
Run Code Online (Sandbox Code Playgroud)
显然,第二个表达式根据DST规则扣除两个小时,其中第一个表达式仅使用标准偏移量.
我检查了这两个时区名称的目录.他们都在那里,看起来一样:
db=# SELECT * FROM pg_timezone_names WHERE name IN ('CET', 'Europe/Vienna');
name | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
Europe/Vienna | CEST | 02:00:00 | t
CET | CEST | 02:00:00 | t
Run Code Online (Sandbox Code Playgroud)
我查阅了关于时区的PostgreSQL手册:
PostgreSQL允许您以三种不同的形式指定时区:
全时区名称,例如America/New_York.识别的时区名称列在pg_timezone_names视图中(参见第45.67节).PostgreSQL为此目的使用广泛使用的zoneinfo时区数据,因此许多其他软件也识别相同的名称.
时区缩写,例如PST.这样的规范仅定义了与UTC的特定偏移,而不是全时区名称,其也可以暗示一组夏令时转换日期规则.公认的缩写列在pg_timezone_abbrevs视图中(参见第45.66节).您不能将配置参数timezone或log_timezone设置为时区缩写,但可以在日期/时间输入值和AT TIME ZONE运算符中使用缩写.
大胆的重点我的.
为什么差异呢?
关于Debian …
我正在尝试维护一个地址历史表:
CREATE TABLE address_history (
person_id int,
sequence int,
timestamp datetime default current_timestamp,
address text,
original_address text,
previous_address text,
PRIMARY KEY(person_id, sequence),
FOREIGN KEY(person_id) REFERENCES people.id
);
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种简单的方法可以自动编号/约束sequence,address_history从而自动从1开始计数person_id.
换句话说,第一行person_id = 1会得到sequence = 1; person_id = 1会得到第二排sequence = 2.第一行person_id = 2,将sequence = 1再次获得.等等.
还有更好/内置的方式来维护这样的历史吗?
环境
问题
我正在构建一个Spring Boot微服务,它与不同的服务共享一个Postgresql数据库.数据库在外部初始化(在我们的控制之外),其他服务使用的日期时间列类型是没有时区的时间戳.因此,由于我希望db上的所有日期具有相同的类型,因此具有该类型是我的JPA实体日期的要求.
我在JPA实体对象上映射它们的方式如下:
@Column(name = "some_date", nullable = false)
private Timestamp someDate;
Run Code Online (Sandbox Code Playgroud)
问题是,当我按如下方式创建时间戳时:
new java.sql.Timestamp(System.currentTimeMillis())
Run Code Online (Sandbox Code Playgroud)
我查看数据库,时间戳包含我当地的时区日期时间,但我想将其存储在UTC中.这是因为我的默认时区设置为'Europe/Brussels',JPA/JDBC将我的java.sql.Timestamp对象转换为我的时区,然后再将其放入数据库.
找不到理想的解决方案
TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));具有我想要实现的效果,但它不适合,因为它不是特定于我的服务.即它会影响整个JVM或当前线程加上孩子.
启动应用程序-Duser.timezone=GMT似乎也为正在运行的JVM的单个实例执行任务.因此,比前一个更好的解决方案.
但有没有办法在JPA/datasource/spring启动配置中指定时区?
我有一个类型为 nullable 的列timestamp without time zone。它以以下格式存储在我的 Postgres 数据库中:2021-06-24 11:00:00. 我想将其转换为可为空的timestamp with time zone类型,以便将其显示为2021-06-24 11:00:00.000-00. 请注意,没有时区转换。
该解决方案还应该允许从 转换timestamp with time zone为timestamp without time zone。我做了一些研究,但没有找到任何东西。
我有一个名为PostgreSQL的表queries_query,它有很多列.
其中两个列created和user_sid我的应用程序经常在SQL查询中一起使用,以确定给定用户在过去30天内完成了多少查询.在最近30天之前的任何时间查询这些统计数据是非常非常罕见的.
这是我的问题:
我目前通过运行以下方法在这两列上创建了我的多列索引:
CREATE INDEX CONCURRENTLY some_index_name ON queries_query (user_sid, created)
Run Code Online (Sandbox Code Playgroud)
但我想进一步限制索引只关心创建日期在过去30天内的查询.我尝试过以下方法:
CREATE INDEX CONCURRENTLY some_index_name ON queries_query (user_sid, created)
WHERE created >= NOW() - '30 days'::INTERVAL`
Run Code Online (Sandbox Code Playgroud)
但这引发了一个异常,说明我的函数必须是不可变的.
我很乐意让这个工作,以便我可以优化我的索引,并削减Postgres需要执行这些重复查询的资源.
我有两个数据库在不同时区的不同服务器上运行.有几个表包含timestamp with timezone.
我需要从一个数据库转储数据,并使用正确的时间戳和正确的时区将其导入另一个数据库.
我使用以下命令来转储数据:
pg_dump -a DB_NAME > dump.sql
Run Code Online (Sandbox Code Playgroud)
我看到数据采用旧时间戳和时区格式: 2013-11-29 14:30:00+02
然后我使用命令到另一台服务器来恢复转储:
psql -d DB_NAME -f dump.sql
Run Code Online (Sandbox Code Playgroud)
我看到时间戳和时区来自旧服务器 - 我认为这是正常的.
然后我尝试在dump.sql的开头添加以下命令
SET timezone ...
Run Code Online (Sandbox Code Playgroud)
但仍然行不通.:(
这是一次性操作.一旦传输数据不需要同步.有没有办法使用pg_dump和pg_restore或类似的方式进行此类转换?
为什么下面的查询计划中包含表“events_201504”?根据我的查询和该表的检查约束,我希望查询规划器能够完全修剪它:
database=# \d events_201504
Table "public.events_201504"
Column | Type | Modifiers
---------------+-----------------------------+---------------------------------------------------------------
id | bigint | not null default nextval('events_id_seq'::regclass)
created_at | timestamp without time zone |
Indexes:
"events_201504_pkey" PRIMARY KEY, btree (id)
"events_201504_created_at" btree (created_at)
Check constraints:
"events_201504_created_at_check" CHECK (created_at >= '2015-04-01 00:00:00'::timestamp without time zone AND created_at <= '2015-04-30 23:59:59.999999'::timestamp without time zone)
Inherits: events
Run Code Online (Sandbox Code Playgroud)
时间及配置:
database=# select now();
now
-------------------------------
2015-05-25 16:49:20.037815-05
database=# show constraint_exclusion;
constraint_exclusion
----------------------
on
Run Code Online (Sandbox Code Playgroud)
查询计划:
database=# explain select count(1) from events where created_at …Run Code Online (Sandbox Code Playgroud) sql postgresql database-partitioning postgresql-performance postgresql-9.3
我想改进这个慢查询,我想添加一个索引,但我不知道哪种索引类型更适合我的情况。
SELECT COUNT(*) ct FROM events
WHERE dtt AT TIME ZONE 'America/Santiago'
>= date(now() AT TIME ZONE 'America/Santiago') + interval '1s'
Run Code Online (Sandbox Code Playgroud)
查询计划:
"Aggregate (cost=128032.03..128032.04 rows=1 width=0) (actual time=3929.083..3929.083 rows=1 loops=1)"
" -> Seq Scan on events (cost=0.00..125937.68 rows=837742 width=0) (actual time=113.080..3926.972 rows=25849 loops=1)"
" Filter: (timezone('America/Santiago'::text, dtt) >= (date(timezone('America/Santiago'::text, now())) + '00:00:01'::interval))"
" Rows Removed by Filter: 2487386"
"Planning time: 0.179 ms"
"Execution time: 3929.136 ms"
Run Code Online (Sandbox Code Playgroud)
注意:根据 Erwin 的建议,查询运行得更快一些,但我认为还不够快。
"Aggregate (cost=119667.76..119667.77 rows=1 width=0) (actual …Run Code Online (Sandbox Code Playgroud) postgresql ×10
sql ×5
timezone ×5
timestamp ×4
date ×2
indexing ×2
count ×1
datetime ×1
java ×1
jpa ×1
pg-dump ×1
pg-restore ×1
plpgsql ×1
spring-boot ×1