我有一个PostgreSQL 9.5表,该表设置为在主键ID达到最大值时循环运行。出于参数考虑,让最大ID值可以为999,999。我将添加逗号以使数字更易于阅读。
我们运行了一个作业,该作业会删除早于45天的表中的数据。假设该表现在仅包含ID为999,998和999,999的记录。
主键ID循环回到1,并且已经写入了20条记录。我需要保持通用性,这样就不会对写入的数量做任何假设。在我的现实世界需求中,我不在乎写了多少书。
如何选择记录而不会获得ID为999,998和999,999的重复记录?
例如:
SELECT * FROM my_table WHERE ID >0;
Would return (in no particular order):
999,998
999,999
1
2
...
20
我的现实情况是,我需要将所有写入表的记录发布到消息代理。我维护一个单独的表,该表跟踪发布的最后一条记录的行ID和时间戳。确定要写入哪些新记录的伪查询/伪算法就是这样。 IF语句处理主键ID何时回到1,因为我需要读取ID循环之后写入的新记录:
SELECT * from my_table WHERE id > last_written_id
PUBLISH each record
if ID of last record published == MAX_TABLE_ID (e.g 999,999):
??? What to do here? I need to get the newest records where ID >= 1 but less than the oldest record I have
我意识到“代码”很粗糙,但是目前它只是一个想法,因此没有代码。
谢谢
答案 0 :(得分:1)
嗯,您可以使用序列的当前值执行所需的操作:
select t.*
from my_table t
where t.id > @last_written_id or
(currval(pg_get_serial_sequence('my_table', 'id')) < @last_written_id and
t.id <= currval(pg_get_serial_sequence('my_table', 'id'))
);
这不是100%的解决方案。毕竟,可能已经添加了2,000,000条记录,所以这些数字将全部重复或删除记录。另外,如果在查询运行时发生插入操作-尤其是在多线程环境中。
答案 1 :(得分:0)
这是一种完全不同的方法:您可以完全填满表格,在表格中为其指定删除时间。因此,您只需设置此日期时间,而不是删除行。而不是插入一行,您只需更新最长时间前删除的那一行即可:
update my_table
set col1 = 123, col2 = 456, col3 = 'abc', deletion_datetime = null
where deletion_datetime =
(
select deletion_datetime
from my_table
where deletion_datetime is not null
order by deletion_datetime
limit 1
);
答案 2 :(得分:0)
如果您可以假定该范围的填充因子小于0.5,则效果很好:
import RPi.GPIO as GPIO
import serial
import time,sys
var=0b11110000
SERIAL_PORT = "/dev/ttyS0"
ser=serial.Serial(SERIAL_PORT,baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS)
time.sleep(1)
print("Sending")
ser.write(var)
ser.close()