如何创建每天从 1 开始的序列
How to create sequence which start from 1 in each day
序列应 return 值为 1、2、3 等,每天从 1 开始。
current_date 应该用于日期确定。
比如今天第一次打电话应该return1,第二次2等等
明天,第一个电话应该 return 再次 1,第二个电话 2 等等
使用 Postgres 9.1。
您只需要将 cronjob 视为 运行 在指定时间或日期执行的 shell 命令。
Shell 运行 cron 作业的命令
psql --host host.domain.com --port 32098 --db_name 数据库名 < my.sql
然后您可以将其添加到您的 crontab 中(我建议您使用 crontab -e 来避免破坏)
# It will run your command at 00:00 every day
# min hour wday month mday command-to-run
0 0 * * * psql --host host.domain.com --port 32098 --db_name databaseName < my.sql
这是一个很有趣的任务。
让我们尝试使用日期的附加序列和替代函数来获取下一个值:
-- We will use anonymous block here because it is impossible to use
-- variables and functions in DDL directly
do language plpgsql $$
begin
execute 'create sequence my_seq_day start with ' || (current_date - '1900-01-01')::varchar;
end; $$;
-- Initialize sequence
select nextval('my_seq_day');
create sequence my_seq;
create or replace function nextval_daily(in p_seq varchar) returns bigint as $$
declare
dd bigint;
lv bigint;
begin
select current_date - '1900-01-01'::date into dd;
-- Here we should to retrieve current value from sequence
-- properties instead of currval function to make it session-independent
execute 'select last_value from '||p_seq||'_day' into lv;
if dd - lv > 0 then
-- If next day has come
-- Reset main sequens
execute 'alter sequence '||p_seq||' restart';
-- And set the day sequence to the current day
execute 'alter sequence '||p_seq||'_day restart with '||dd::varchar;
execute 'select nextval('''||p_seq||'_day'')' into lv;
end if;
return nextval(p_seq);
end; $$ language plpgsql;
然后使用函数 nextval_daily
而不是 nextval
。
希望对您有所帮助。
使用一个table来保持顺序:
create table daily_sequence (
day date, s integer, primary key (day, s)
);
此函数将检索下一个值:
create or replace function daily_sequence()
returns int as $$
insert into daily_sequence (day, s)
select current_date, coalesce(max(s), 0) + 1
from daily_sequence
where day = current_date
returning s
;
$$ language sql;
select daily_sequence();
准备好在出现不可能的 duplicate key value
错误时重试。如果不需要前几天的序列,请删除它们以保持 table 和索引尽可能轻:
create or replace function daily_sequence()
returns int as $$
with d as (
delete from daily_sequence
where day < current_date
)
insert into daily_sequence (day, s)
select current_date, coalesce(max(s), 0) + 1
from daily_sequence
where day = current_date
returning s
;
$$ language sql;
我遇到过几乎类似的需求。
处理查询中的逻辑而不是修改序列。
使用 setval() 将序列重置为 0 如果它是当天第一个进入 table 的条目。
Else nextval() 序列的
下面是示例查询:
SELECT
CASE WHEN NOT EXISTS (
SELECT primary_key FROM schema.table WHERE date(updated_datetime) = #{systemDate} limit 1)
THEN
setval('scheam.job_seq', 1)
ELSE
nextval('scheam.job_seq')
END
UPDATE 用户需要权限才能执行 setval。
GRANT UPDATE ON ALL SEQUENCES IN SCHEMA ur_schema TO user;
序列应 return 值为 1、2、3 等,每天从 1 开始。 current_date 应该用于日期确定。
比如今天第一次打电话应该return1,第二次2等等
明天,第一个电话应该 return 再次 1,第二个电话 2 等等
使用 Postgres 9.1。
您只需要将 cronjob 视为 运行 在指定时间或日期执行的 shell 命令。
Shell 运行 cron 作业的命令 psql --host host.domain.com --port 32098 --db_name 数据库名 < my.sql
然后您可以将其添加到您的 crontab 中(我建议您使用 crontab -e 来避免破坏)
# It will run your command at 00:00 every day
# min hour wday month mday command-to-run
0 0 * * * psql --host host.domain.com --port 32098 --db_name databaseName < my.sql
这是一个很有趣的任务。
让我们尝试使用日期的附加序列和替代函数来获取下一个值:
-- We will use anonymous block here because it is impossible to use
-- variables and functions in DDL directly
do language plpgsql $$
begin
execute 'create sequence my_seq_day start with ' || (current_date - '1900-01-01')::varchar;
end; $$;
-- Initialize sequence
select nextval('my_seq_day');
create sequence my_seq;
create or replace function nextval_daily(in p_seq varchar) returns bigint as $$
declare
dd bigint;
lv bigint;
begin
select current_date - '1900-01-01'::date into dd;
-- Here we should to retrieve current value from sequence
-- properties instead of currval function to make it session-independent
execute 'select last_value from '||p_seq||'_day' into lv;
if dd - lv > 0 then
-- If next day has come
-- Reset main sequens
execute 'alter sequence '||p_seq||' restart';
-- And set the day sequence to the current day
execute 'alter sequence '||p_seq||'_day restart with '||dd::varchar;
execute 'select nextval('''||p_seq||'_day'')' into lv;
end if;
return nextval(p_seq);
end; $$ language plpgsql;
然后使用函数 nextval_daily
而不是 nextval
。
希望对您有所帮助。
使用一个table来保持顺序:
create table daily_sequence (
day date, s integer, primary key (day, s)
);
此函数将检索下一个值:
create or replace function daily_sequence()
returns int as $$
insert into daily_sequence (day, s)
select current_date, coalesce(max(s), 0) + 1
from daily_sequence
where day = current_date
returning s
;
$$ language sql;
select daily_sequence();
准备好在出现不可能的 duplicate key value
错误时重试。如果不需要前几天的序列,请删除它们以保持 table 和索引尽可能轻:
create or replace function daily_sequence()
returns int as $$
with d as (
delete from daily_sequence
where day < current_date
)
insert into daily_sequence (day, s)
select current_date, coalesce(max(s), 0) + 1
from daily_sequence
where day = current_date
returning s
;
$$ language sql;
我遇到过几乎类似的需求。
处理查询中的逻辑而不是修改序列。 使用 setval() 将序列重置为 0 如果它是当天第一个进入 table 的条目。 Else nextval() 序列的
下面是示例查询:
SELECT
CASE WHEN NOT EXISTS (
SELECT primary_key FROM schema.table WHERE date(updated_datetime) = #{systemDate} limit 1)
THEN
setval('scheam.job_seq', 1)
ELSE
nextval('scheam.job_seq')
END
UPDATE 用户需要权限才能执行 setval。
GRANT UPDATE ON ALL SEQUENCES IN SCHEMA ur_schema TO user;