I am trying to increment sequence on id of table. But I don't know sequence name because it's default sequence that postgresql generated.
I have read questions like these:
ALTER postgreSQL sequence
but they don't really answer my question because I don't know name of sequence. I tried:
ALTER SEQUENCE table_name_id_seq INCREMENT BY 1;
but it didn't work.
You can retreive the name of the sequence from the table/column names.
Then you can use setval to set the current value. In the example below, it sets the value to the biggest found value (next one will be +1)
SELECT setval(
pg_get_serial_sequence('myschema.mytable','mycolumn'),
max(mycolumn))
FROM myschema.mytable;
Related
What is the benefit to use sequence rather than just insert and get generated ID in postgresql ?
I mean why don't just insert a record and the rdbms generate ID for you?
For most purposes, SERIAL does the same thing as a sequence can do. However, if you wanted your auto increment column to have a custom behavior, you might have to use a sequence. For example, let's say that you wanted the sequence to start at 100. Then you could use:
CREATE SEQUENCE your_seq
START 101
INCREMENT 1;
INSERT INTO yourTable (id, val)
VALUES (NEXTVAL('your_seq'), 'some text here');
I try to set my start increment value but I "get relation does not exist". I have a table named student and a column named student_id.
ALTER SEQUENCE student_student_id_seq RESTART WITH 18354001
I tried to use double and single quotes but it does not work.
I know that is simple and so general question but I could not handle it.
You can find the sequence associated to a given table/column using
select pg_get_serial_sequence('myschema.mytable','mycolumn');
I have a table called jobs in Postgres, which has columns job_id, username, created_ts and other job related informations. Column job_id is of serial type.
...
job_id serial NOT NULL,
username character varying(32),
...
username denotes the user who created the job. An user can only see the jobs which are created by him. He can see the job_id also. This makes the user to see random job_ids, not strictly sequence.
I want to make the sequence start from 1 for each user. It has to be sequential with respect to username. This will create duplicate job_ids but that's okay.
I have referred https://www.postgresql.org/docs/9.5/static/sql-createsequence.html I couldn't find any way to create a sequence by column value. Is it possible to create such sequence generator in Postgres?
I don't know if you can do that with sequences, but unless someone can think of something better, you could remove the sequence and instead have a trigger on INSERT that does something like
NEW.job_id := COALESCE((SELECT MAX(job_id) FROM jobs WHERE username = NEW.username), 0) + 1;
As long as you have the appropriate indexes it should be perfectly fast. Though I can foresee issues with concurrency. Depends how you expect to use it.
Whenever I am creating a table in Postgres, I like using SERIAL as primary key so that I don't do duplicates. But I have not been able to set a starting value for this. Let say I am creating student IDs that all have to be 8 digits, but SERIAL always starts from 1, how can I choose the starting value and then just increment from there? I have looked through the answered questions but I couldn't find the answer. Thanks!
Use setval() to change the sequence and pg_get_serial_sequence() to obtain the name of the sequence:
select setval(pg_get_serial_sequence(table_name, column_name), 9999999);
I have a list of integer values X and I want a primary key for my table Y to come from that list of integer values. I was wondering if this could be done using sequences. In other words: is there a way to tell a PostgreSQL sequence to use this list X to generate primary keys for my table Y?
One way of doing this would be to use a sequence that contains the index of the last used integer from the list X, call setval() on the sequence, get the next value and try to insert it into my table Y. In case of concurrent requests there will be an error, in which case I need to try with the next value from the list X. I would like to know what other (better) ways there are to achieve what I intend to do.
Could work like this:
-- DROP SCHEMA x CASCADE;
CREATE SCHEMA x;
CREATE TABLE x.priv_id(seq_id int primary key, id int);
INSERT INTO x.priv_id
SELECT generate_series(1,100,1), (random() * 1000)::int;
CREATE SEQUENCE x.priv_seq;
SELECT id
FROM x.priv_id
WHERE seq_id = (SELECT nextval('x.priv_seq'));
Major points:
1) Create a lookup table with two numbers
- seq_id is counting from 1 and your primary key.
- id is your numbers in sequence (I substituted random numbers here).
2) Create a helper sequence.
3) Get your numbers with a SELECT like above.
You need the subselect, or all values will be returned at once.
This solution gives all the security nextval() has to offer for concurrency.
Create a unique index on priv_id(id) if you want to make sure your custom id's are unique.
generate_series can be used to produce a list of all numbers every generated by a sequence:
select *
from generate_series(1, (select last_value from my_sequence), 1) as x
Note: This assumes the sequence (here my_sequence) started at 1 and incremented by 1. To change these assumptions, change the parameters appropriately.
The most general way to provide your own set of valid numbers is to store them in a table, and set a foreign key reference to it.
That solves the problem of using your own list, but it doesn't solve the problem of fetching the next number from the list. To do that, you'd need to write your own function. (You can't compel a PostgreSQL sequence to operate on your table instead of using its internals.) It's not particularly hard to do, though.
Another alternative that's often overlooked--perhaps with good reason--is writing your own sequence. PostgreSQL is open source; you can write your own sequencer based on existing sequence code. Compile it, test it, and you're off to the races. (I don't recommend doing that, though.)