postgresql nextval incorrect result - sql

After restoring database I run next query
SELECT nextval('table_id_seq')
and I must get max id + 1 something like (select max(id) + 1 from table), but instead I get just max id next time I call it result is correct. This issue happens only to two tables the rest works okay. I use PostgreSQL 10.
Any ideas what it can be.

Check "last value" of sequence using below query:
select * from sequence_name
If the last value does not match with table max value then use alter sequence and restart the last value as table max value.

Related

Alter / Update PostgreSQL Sequence

How can I update the last_value field in my sequence and add 1 to it?
The query I tried: ALTER SEQUENCE "seq_hours" SET 'last_value' = 'last_value' + 1
However this did not work.
Use setval() with a subquery to get the value from a table, e.g.
SELECT setval('seq_hours', (SELECT max(last_value)+1 FROM t));
EDIT: This solution only makes sense if you want to set the current value of a sequence based on a value from a given table. If you only want the next possible value of a sequence you should use nextval as #a_horse_with_no_name suggested (see comments)

update rows one by one with max value + 1 in SQL

here is my situation,
I have 2 tables,
1st table has all records, and it has IDs
2nd table has new records and it doesnt have ID, yet.
I want to generate ID for 2nd table with max(id) + 1 from 1st table.
when i do this, it makes all rows same id number, but i want to make it unique increment number.
e.g
select max(id) from table1 then it gives '997040'
I want to make second table rows like;
id
997041
997042
997043
997044
i think i need to use cursor or whileloop, or both, but i could not create the actual query.
sorry about bad explanation, i am so confused now
Use ROWNUM to generate incrementing row numbers. E.g.:
SELECT someConstant + ROWNUM FROM source.
CREATE TABLE table_name
(
ID int IDENTITY(997041,1) PRIMARY KEY
)
I hope this sql query would work!!
Or refer http://www.w3schools.com/sql/sql_autoincrement.asp

Query for first occurence of null value in SQLite

I have a table which I dynamically fill with some data I want to create some statistics for. I have one value which has some values following a certain pattern, so I created an additional column where I map the values to other values so I can group them.
Now before I run my statistics, I need to check if I have to remap these values which means that I have to check if there are null values in that column.
I can do a select like this:
select distinct 1
from my-table t
where t.status_rd is not null
;
The disadvantage is, that this returns exactly one row, but it has to perform a full select. Is there some way that I can stop the select for the first encounter? I'm not interested in the exact row, because when there is at least one row, I have to run an update on all of them anyway, but I would like to avoid running the update unnecessarily everytime.
In Oracle I would do it with rownum, but this doesn't exist in SQLite
select 1
from my-table t
where t.status_rd is not null
and rownum <= 1
;
Use LIMIT 1 to select the first row returned:
SELECT 1
FROM my_table t
WHERE t.status_rd IS NULL
LIMIT 1
Note: I changed the where clause from IS NOT NULL to IS NULL based on your problem description. This may or may not be correct.

How to return record count in PostgreSQL

I have a query with a limit and an offset. For example:
select * from tbl
limit 10 offset 100;
How to keep track of the count of the records, without running a second query like:
select count(*) from tbl;
I think this answers my question, but I need it for PostgreSQL. Any ideas?
I have found a solution and I want to share it. What I do is - I create a temp table from my real table with the filters applied, then I select from the temp table with a limit and offset (no limitations, so the performance is good), then select count(*) from the temp table (again no filters), then the other stuff I need and last - I drop the temp table.
select * into tmp_tbl from tbl where [limitations];
select * from tmp_tbl offset 10 limit 10;
select count(*) from tmp_tbl;
select other_stuff from tmp_tbl;
drop table tmp_tbl;
I haven't tried this, but from the section titled Obtaining the Result Status in the documentation you can use the GET DIAGNOSTICS command to determine the effect of a command.
GET DIAGNOSTICS number_of_rows = ROW_COUNT;
From the documentation:
This command allows retrieval of system status indicators. Each item
is a key word identifying a state value to be assigned to the
specified variable (which should be of the right data type to receive
it). The currently available status items are ROW_COUNT, the number of
rows processed by the last SQL command sent down to the SQL engine,
and RESULT_OID, the OID of the last row inserted by the most recent
SQL command. Note that RESULT_OID is only useful after an INSERT
command into a table containing OIDs.
Depends if you need it from the psql CLI or if you're accessing the database from something like an HTTP server. I am using postgres from my Node server with node-postgres. The result set is returned as an array called 'rows' on the result object so I can just do
console.log(results.rows.length)
To get the row count.

select max value of a column in table with no rows

I am using oracle database
While inserting a row in a table, i need to find the max value of a column and increment it by 1, and use that value in row i am inserting.
INSERT INTO dts_route
(ROUTE_ID, ROUTE_UID, ROUTE_FOLDER)
VALUES (
(SELECT MAX(ROUTE_ID) + 1 FROM route) ,
ROUTE_UID,
ROUTE_FOLDER)
This works fine if their is at least one entry in table.
But returns null when their are no entries in table.
How can i get default value of 1 when their are no entries in table.
SELECT COALESCE(MAX(ROUTE_ID),0) ...
This is not a safe way of creating an auto-increment field. You can use an Oracle sequence to achieve this goal.
As for the null, you can use NVL to give a default value (say, 0) in case the function returns null.
Use sequence for the ID. You need to create sequence. See below link
http://www.basis.com/onlinedocs/documentation/b3odbc/sql_sequences.htm
Use:
INSERT INTO dts_route
(ROUTE_ID)
SELECT COALESCE(MAX(r.route_id), 0) +1
FROM ROUTE r
...but you really should be using a sequence to populate the value with a sequential numeric value:
CREATE SEQUENCE dts_route_seq;
...
INSERT INTO dts_route
(ROUTE_ID)
SELECT dts_route_seq.NEXTVAL
FROM DUAL;
Set a default for NULL
SELECT NVL(MAX(ROUTE_ID),0)
though using a sequence might be easier if you don't mind the odd gaps in your route ids
select 0 when null, then it will be 0+1 which is a correct number compared to null+1
SELECT isnull(MAX(ROUTE_ID),0) + 1 FROM route
If you are concerned about there being gaps in your route ids then create the sequence with the NOCACHE clause:
CREATE SEQUENCE dts_route_seq NOCACHE;
Note that there is a performance hit because Oracle now has to "commit" each time you increment the sequence.