AutoID column for a table - sql

I was asked by my manager to add an AutoID column to the table UserTracking, so that all the existing entries could be populated with a value, and for this to be in the same order as the CreateDate field (i.e. ID 1 is in the earliest entry).
I did this:
alter table dbo.UserTracking add AutoID bigint NULL
go
update dbo.UserTracking
set AutoId=AutoId.AutoId
from dbo.UserTracking as ut
join
(
select CreateDate,row_number() over (order by CreateDate) as AutoId
from UserTracking
) as AutoId
on ut.CreateDate=AutoId.CreateDate
go
create index IDX__UserTracking__AutoId on dbo.UserTracking (AutoId)
go
BUT I was told that we need the AutoID column to be an actual auto ID (so that it has automatic new values on record insert) and it should be called ID to be consistent with other tables.
From performance point of view it would be perfect if the new ID (INT) column is our primary key but it can be hard to do. For now we need the auto ID with an index on it.
I'm not entirely sure how to do it myself and I wouldn't want to mess it up. Could someone please help?

Drop the existing column (AutoID) , you cannot make an existing column an Identity column.
Just add another column and make it Identity column.
ALTER TABLE dbo.UserTracking
ADD ID INT IDENTITY(1,1)
GO
It will populates the column itself you don't have to do anything .

Related

How to alter PostgreSQL column with entries to be a nextval id

I have a problem with a really big database with following scheme:
id | date | other columns...
The id column is from type integer. It would be ideal if it where from type integer with a nextval constraint. Many of the id entries have unique id's incremented when they where added.
The problem is all rows added since a specific date have no id and the value is null.
Is it possible to add such constraints to tables with existing values (plus null values) so that the null values are filled with integer id's?
And is this possible without losing the old id's and in the best case with ascending order in relation to the date column?
thanks and greetings
You need to first update the existing rows with a unique, non-null value:
update the_table
set id = new_id
from (
select ctid,
(select max(id) from the_table) + row_number() over (order by date) as new_id
from the_table
where id is null
) t
where t.ctid = the_table.ctid;
I am not sure if the order of the IDs is guaranteed using this approach, but it's likely that it does.
Now, that the column doesn't contain any NULL values, we can either change it automatically assign new values.
The next steps depend on whether you want to make this an identity column or simply a column with a default from a sequence (essentially a (discouraged) serial column)
Staying with a "serial"
We need to create a sequence and sync it with the highest value in the column.
create sequence the_table_id_seq;
select setval('the_table_id_seq', max(id))
from the_table;
Then use this for the default and link the sequence to the column.
alter table the_table
alter id set not null,
alter id set default nextval('the_table_id_seq') ;
alter sequence the_table_id_seq owned by the_table.id;
Using an identity column (recommended)
To make this a proper (recommended) identity column (Postgres 10 and later) you can do it like this:
alter table the_table
alter id set not null,
alter id add generated always as identity;
Now adding the identity attribute created a new sequence which we need to sync with the existing values in the column:
select setval(pg_get_serial_sequence('the_table', 'id'), max(id))
from the_table;
Alternatively, you could have manually looked up the current max value and provide that directly when specifying the identity default:
alter table the_table
alter id set not null,
alter id add generated always as identity (start with 42);

PostgreSQL - create an auto-increment column for non-primary key

I am with PostgreSQL 9.5 X64 integrated with the open-source Parse Server. My table has the following structure.
objectId (text with fixed 10 characters),
item_id (integer),
item_name (text with various length)
The objectId is the primary key due to use of Parse Server. It is automatically generated by Parse Server. The item_id is not a primary key. I would like to have item_id automatically increment by 1 when a new record is created. How can this be achieved in Create Table?
Add a default value with a sequence:
CREATE SEQUENCE mytable_item_id_seq OWNED BY mytable. item_id;
ALTER TABLE mytable ALTER item_id SET DEFAULT nextval('mytable_item_id_seq');
To make that work, you have to exclude the item_id column from all INSERT statrments, because the default value is only used if no value is specified for the column.
You may try making the item_id column SERIAL. I don't know whether or not it's possible to alter the current item_id column to make it serial, so we might have to drop that column and then add it back, something like this:
ALTER TABLE yourTable DROP COLUMN item_id;
ALTER TABLE yourTable ADD COLUMN item_id SERIAL;
If there is data in the item_id column already, it may not make sense from a serial point of view, so hopefully there is no harm in deleting it.

SQL sever, Make a existing column primary and set to auto increment

I have old SQL sever table with 5000 rows. It has a column called OrderID which has the data type int. But this table doesn't have a primary key and OrderID is not on the sorted order. Can you please tell me how can I make this OrderID column the primary key and make it auto increment
You can't add identity to an existing column.
Your best option is to create a new table with the same structure and an identity column, set identity_insert on and then copy your records from the old one into the new one.
Check out this answer from the MS SQL Forum
You can't add identity to existing column. Create a new column "new_OderId" , copy data from "OderId" column paste in "new_OderId" column.
#add new column to Order_table
alter table Order_table add new_OderId int
#copy data from OrderId to new_OrderId
update Order_table set new_OrderId=OderId
#drop OderId column
alter table Order_table drop column OrderId

SQL Server: how to add new identity column and populate column with ids?

I have a table with huge amount of data. I'd like to add extra column id and use it as a primary key. What is the better way to fill this column with values from one 1 to row count
Currently I'm using cursor and updating rows one by one. It takes hours. Is there a way to do that quicker?
Thank you
Just do it like this:
ALTER TABLE dbo.YourTable
ADD ID INT IDENTITY(1,1)
and the column will be created and automatically populated with the integer values (as Aaron Bertrand points out in his comment - you don't have any control over which row gets what value - SQL Server handles that on its own and you cannot influence it. But all rows will get a valid int value - there won't be any NULL or duplicate values).
Next, set it as primary key:
ALTER TABLE dbo.YourTable
ADD CONSTRAINT PK_YourTable PRIMARY KEY(ID)
If you want to add row numbers in a specific order you can do ROW_NUMBER() into a new table then drop the original one. However, depending on table size and other business constraints, you might not want to do that. This also implies that there is a logic according to which you will want the table sorted.
SELECT ROW_NUMBER() OVER (ORDER BY COL1, COL2, COL3, ETC.) AS ID, *
INTO NEW_TABLE
FROM ORIGINAL_TABLE

How reorder primary key?

I have deleted one row(row 20) in my "table category" ,please let me know that how can i reorder the catid (primary key)? at this time it is 21 after 19.
Thanks
You cannot. The closest you can get is truncate table, which will drop the table and recreate it, which means you lose all data in it, and the ID counter is reset to 0. Other than that, ID will always increment by one from the last inserted record, no matter if that record still exists or not. You can write a query to fix all your current IDs, of course, but upon next insert, it'll still create a new gap. More to the point: if a sequential ordering without gaps is what you want, auto incremental ID is not the proper way to achieve that. Add another int field where you manually keep track of this ordering.
If you care enough about your primary key values that such a value is unwanted, you shouldn't be using auto-number primary keys in the first place.
The whole point with a auto-number key is that you say "As long as the key is unique, I don't really care about its value."
Don't mess with the primary keys. They should never change and you should not use them in your app for anything but joining tables.
Add a new column if you need a gapless index and update this column accordingly when you do inserts/removes. This might sound like useless work for you right now, but it will save you a lot of pain later.
Try this:
UPDATE tbl SET catid = (SELECT COUNT(*) FROM tbl t WHERE t.catid <= tbl.catid);
You might also want to rethink / redesign. Renumbering the entire table when you delete a row doesn't seem likely to be either practical or necessary.
Actually you can.
If your rows have unique enough data and you are using PHPmyAdmin
Delete the Column with the Primary ID
Read the Column with Primary Key and Auto Increment enabled.
What do you mean by reordering primary key? If you are saying that you want the primary key to take 20 instead of 21, then I afraid you can't do that straightaway.
All you can do, is to drop the primary key constraint, then change the 21 to 20, and reapply back the primary key constraint
David is right about not using primary key for indexing and such.
If you'll just have to change a particular primary key value once (I've done it sometimes during migration) you could of course set identity_insert on and copy the row with a insert select and then delete the original one.
For recreating a sort order or an column used as an index in your application you could use the following stored procedure:
CREATE PROCEDURE [dbo].[OrganizeOrderConfirmationMessages]
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sortOrder INT;
SET #sortOrder = 0;
-- // Create temporary table
CREATE TABLE #IDs(ID INT, SortOrder INT)
-- // Insert IDs in order according to current SortOrder
INSERT INTO #IDs SELECT ocm.ID, 0 FROM OrderConfirmationMessages ocm ORDER BY ocm.SortOrder ASC
-- // Update SortOrders
UPDATE #IDs SET SortOrder = #sortOrder, #sortOrder = #sortOrder + 10
-- // Update the "real" values with data from #IDs
UPDATE OrderConfirmationMessages SET SortOrder = x2.SortOrder
FROM #IDs x2 WHERE OrderConfirmationMessages.ID = x2.ID
END
Results:
An example of SortOrders will go from 1,2,5,7,10,24,36 to 10,20,30,40,50,60,70
You should drop the 'catid' field and then create it again, set it as primary and check the Auto Increment checkbox, it will add the new field and fill the numbers.
First drop the primary key column from your table and run this syntax in your phpmyadmin sql section-
ALTER TABLE 'your_tablename' ADD 'column_name' BIGINT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY
('column_name' (10));
This will automatically arrange the column in numbers from 0, 1 and so on.
try this:
SET #var:=0;
UPDATE `table` SET `id`=(#var:=#var+1);
ALTER TABLE `table` AUTO_INCREMENT=1;
In postgres, you can do this where number of records < 300:
update schema.tbl1
set tbl_id = tbl_id + 300;
alter sequence schema.tbl1_id_seq
restart with 1;
insert into schema.tbl1
select nextval('schema.tbl1_id_seq'),
column2,
column3
from schema.tbl1;
delete from schema.tbl1
where tbl1_id > 300;