Postgresql - Using subqueries with alter sequence expressions
I don't believe you can do it like that but you should be able to use the setval function direction which is what the alter does.
select setval('sequenceX', (select max(table_id)+1 from table), false)
The false will make it return the next sequence number as exactly what is given.
Postgres manually alter sequence
The parentheses are misplaced:
SELECT setval('payments_id_seq', 21, true); -- next value will be 22
Otherwise you're calling setval
with a single argument, while it requires two or three.
This is the same as SELECT setval('payments_id_seq', 21)
Using result of select inside alter table statement in postgres
Here is one way to do it:
select setval(pg_get_serial_sequence('Table_1', 'id'), coalesce(max(id),0) + 1, false)
from Table_1;
Rationale:
pg_get_serial_sequence()
returns the name of the sequence for the given table and columnset_val()
can be used to reset the sequence- this can be wrapped in a
select
that gives you the current maximum value ofid
in the table (or 1 if the table is empty)
How to reset Postgres' primary key sequence when it falls out of sync?
-- Login to psql and run the following
-- What is the result?
SELECT MAX(id) FROM your_table;
-- Then run...
-- This should be higher than the last result.
SELECT nextval('your_table_id_seq');
-- If it's not higher... run this set the sequence last to your highest id.
-- (wise to run a quick pg_dump first...)
BEGIN;
-- protect against concurrent inserts while you update the counter
LOCK TABLE your_table IN EXCLUSIVE MODE;
-- Update the sequence
SELECT setval('your_table_id_seq', COALESCE((SELECT MAX(id)+1 FROM your_table), 1), false);
COMMIT;
Source - Ruby Forum
PostgreSQL volatile expressions and subqueries
Well, random()
itself is volatile, hence you don't get strings with the same character repeated to the end.
If you look at the plans for the queries with and without b*0
you will see:
With b*0
:
Function Scan on generate_series a (cost=0.00..37530.00 rows=1000 width=4)
SubPlan 1
-> Aggregate (cost=37.51..37.52 rows=1 width=32)
-> Function Scan on generate_series (cost=0.01..25.01 rows=1000 width=0)
Without b*0
:
Function Scan on generate_series a (cost=37.52..47.52 rows=1000 width=0)
InitPlan 1 (returns $0)
-> Aggregate (cost=37.50..37.51 rows=1 width=32)
-> Function Scan on generate_series (cost=0.00..25.00 rows=1000 width=0)
If PostgreSQL determines that the inner aggregation is not dependent on a
, then it is evaluated once as an InitPlan
, and the volatility or not of the expressions within are irrelevant. By introducing the dependency of the subquery on a
, i.e. making it a correlated subquery, the evaluation must be redone for each row of a
.
How to understand the use of the ... Select 1 from ... an expression in SQL
There are two things you need to understand:
- What is a co-related subquery
- How does the (NOT) EXISTS operator work.
A co-related subquery is run once for each row that is returned from the outer query. You can imagine this as a kind of nested loop, where for each row returned by the outer query, the sub-query is executed by using the values of the columns from the outer query.
So if the outer query processes the row for 'ken Adams'
it will take the value 1
from dep_id_fk
and the value 70000
of the column salary and essentially run:
select 1
from employee e2
where e2.dep_id_fk = 1 --<< this value is from the outer query
and e2.salary > 70000 --<< this value if from the outer query
If that query returns no rows, the row from the outer query is included in the result. Then the database proceeds with the next row in the outer query and does the same again until all rows from the outer query are processed and either included in or excluded from the result.
However the NOT EXISTS and EXISTS operators check only check for the presence of rows from the sub-query. The actual value(s) returned from the sub-query are completely irrelevant.
A lot of people incorrectly assume that select 1
is somehow cheaper than select *
in the sub-query - but this is a totally wrong assumption. The expression is never even evaluated, so it's completely irrelevant what is selected there. If you think select *
is more logical than select 1
than use that.
To prove that the expression is never evaluated (or even looked at), you can use one that would otherwise throw an exception.
select *
from employee e
where not exists (select 1/0
from employee e2
where e2.dep_id_fk = e.dep_id_fk
and e2.salary > e.salary);
If you run select 1/0
outside of a sub-query used for an EXISTS or NOT EXISTS condition, it would result in an error. But the EXISTS operator never even looks at the expressions in the SELECT list.
Related Topics
Delete the 'First' Record from a Table in SQL Server, Without a Where Condition
Is Substr or Like Faster in Oracle
Finding the Hash Value of a Row in Postgresql
T-Sql: Separate String into Multiple Columns
Delete Oldest Records from Database
Need to Find Average Processing Time Between All Timestamp Records in Oracle SQL
How to Constraint No Empty Strings on an Nvarchar Column
How to Run .SQL File in Oracle SQL Developer Tool to Import Database
Using MySQL, How to Sort a Column But Have 0 Come Last
What Are the Reasons *Not* to Use a Guid for a Primary Key
How to Select All Columns, and a Count(*) in the Same Query
Connect to SQL via Windows Authentication Over Vpn
Rows to Comma Separated Values Using Xml Tag
SQL Query Selecting Different Row Result in JSON_Modify Because of in Operator Provided Value
SQL Profiler and Tuning Advisor