Adding Unique ID to table - sql-server

I am trying to add a unique ID to an existing table that has data inserted into it. I don't need a new value with each row, rather, with each instance of an insert. The time stamp indicates a new insert. Can anyone be kind enough point me in the right direction? My current table is basically column a and the time stamp.
ID COLUMN A TIME STAMP
1 abc 05-09-2013 11:00:23
1 bcd 05-09-2013 11:00:23
1 ab3 05-09-2013 11:00:23
2 abc 05-09-2013 11:15:00
2 123 05-09-2013 11:15:00
3 abc 05-09-2013 11:18:07
4 abc 05-09-2013 11:19:55
4 123 05-09-2013 11:19:55
4 165 05-09-2013 11:19:55
4 def 05-09-2013 11:19:55

Can't think of any easy way to put unique id based on each insert instance. One idea can be to use trigger on the table where you can inspect how the data getting inserted and add ID value before data gets inserted into table.

First create a ID column which allows null.
Then write a procedure which has a cursor on a query which does a order by and group by on time stamp column.
For every row increase a count by one
update table with id = counter whwre times tamp = time stamp in query
At end of this add constraint on id column to make it not null

You are going to likely want an auto-increment field. Use IDENTITY for this in SQL Server. This will enable you to insert without supplying this p_id value and the value will be auto incremented.
You don't want to use timestamps for uniqueness because it is difficult and costly to index. It is also difficult to ensure uniqueness among time values.
CREATE TABLE Persons
(
P_Id int PRIMARY KEY IDENTITY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)

If your insert is not very frequent. You can use time stamp to get unique Id.
e.g. 130509110023
You can do some math to get appropriate function as required data length, which will give you unique id

Related

Bad design to compare to computed columns?

Using SQL Server I have a table with a computed column. That column concatenates 60 columns:
CREATE TABLE foo
(
Id INT NOT NULL,
PartNumber NVARCHAR(100),
field_1 INT NULL,
field_2 INT NULL,
-- and so forth
field_60 INT NULL,
-- and so forth up to field_60
)
ALTER TABLE foo
ADD RecordKey AS CONCAT (field_1, '-', field_2, '-', -- and so on up to 60
) PERSISTED
CREATE INDEX ix_foo_RecordKey ON dbo.foo (RecordKey);
Why I used a persisted column:
Not having the need to index 60 columns
To test to see if a current record exists by checking just one column
This table will contain no fewer than 20 million records. Adds/Inserts/updates happen a lot, and some binaries do tens of thousands of inserts/updates/deletes per run and we want these to be quick and live.
Currently we have C# code that manages records in table foo. It has a function which concatenates the same fields, in the same order, as the computed column. If a record with that same concatenated key already exists we might not insert, or we might insert but call other functions that we may not normally.
Is this a bad design? The big danger I see is if the code for any reason doesn't match the concatenation order of the computed column (if one is edited but not the other).
Rules/Requirements
We want to show records in JQGrid. We already have C# that can do so if the records come from a single table or view
We need the ability to check two records to verify if they both have the same values for all of the 60 columns
A better table design would be
parts table
-----------
id
partnumber
other_common_attributes_for_all_parts
attributes table
----------------
id
attribute_name
attribute_unit (if needed)
part_attributes table
---------------------
part_id (foreign key to parts)
attribute_id (foreign key to attributes)
attribute value
It looks complicated but due to proper indexing this is super fast even if part_attributes contain billions of records!

Sequential numbering column update

I have a column (line number) that I need to update with sequential numbering starting with 001.
Am I able to run an update for this?
Line 1 001
Line 2 002
Line 3 003
Etc..
You can add a new identity column in your table as below-
ALTER TABLE your_table
ADD ID INT IDENTITY(1,1)
This will add a new column 'ID' to your table and also fill with value starts from 1 to end (row count of the table) with incremental value like 1,2,3.... Once this is done, either you can keep the column, or taking value from this new column you can update your column LineNumber as per your required format.

PostgreSQL Replace Column Data with Unique Integers

I have a table of many columns in Postgresql database. Some of these columns are in text type and have several rows of values. The values also recur. I would like to change these text values with unique integer values.
This is my table column:
Country_Name
------------
USA
Japan
Mexico
USA
USA
Japan
England
and the new column I want is:
Country_Name
------------
1
2
3
1
1
2
4
Each country name is assigned (mapped) to a unique integer and all the recurrences of the text is replaced with this number. How can I do this?
Edit 1: I want to replace my column values on the fly if possible. I don't actually need another column to keep the names but it would be nice to see the actual values too. Is it possible to do:
Create a column country_id with the same values of country_name column in the same table
And for country_id replace each name with a unique integer with an update statement or procedure without requiring a new table or dictionary or map.
I don't know if this is possible but this will speed up things because I have a total of 220 columns and millions of rows. Thank you.
assuming the country_name column is in a table called country_data
create a new table & populate with unique country_names
-- valid in pg10 onwards
-- for earlier versions use SERIAL instead in the PK definition
CREATE TABLE countries (
country_id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
country_name TEXT);
INSERT INTO countries (country_name)
SELECT DISTINCT country_name
FROM country_data;
alter the table country_data & add a column country_id
ALTER TABLE country_data ADD COLUMN country_id INT
Join country_data to countries and populate the country_id column
UPDATE country_data
SET country_id = s.country_id
FROM countries
WHERE country_data.country_name = countries.country_name
At this point the country_id is available to query, but a few following actions may be recommended depending on the use case:
set up country_data.country_id as a foreign key referring to countries.country_id
drop the column country_data.country_name as that's redundant through the relationship with countries
maybe create an index on country_data.country_id if you determine that it will speed up the queries you normally run on this table.

SQL Server identity column and imports

I'll try and explain in simple terms leaving out the whys and wheres of how this occured.
Currently there are 2 databases that need to be merged, they have the same tables etc and in some cases lookup tables are identical, in some cases they are and in some cases records in one database have different identity values for there equivalent in the other DB. So it's a mess.
Let us say on one of the databases we update all the identity values bu adding 10,000 to them and updating the related records. Then we could import the data as is and yes in some cases lookups would have the same value twice with different identities.
The question will not be regarding the above mess :). I want to know after re enabling the identity column we will have seed values of
1,2,3,4,5 etc and 10001, 10002, 10003 etc. Should more rows be inserted and they continue from lets just say 9999 will the identity column use 10,000 and then 10,004 or will SQL Server complain on the next insert that the identity value is already used?
I just tested this with simple INSERT's: you have to disable IDENTITY_INSERT first for each table you want to import data
SET IDENTITY_INSERT table OFF
Then you can insert your data with their original identity column values (which you'll need in order to maintain the references correctly)
After
SET IDENTITY_INSERT table ON
SQL Server continues the sequence with the highest element plus one, so in your case (after inserting IDs 10001, 10002, 10003) it would continue with 10004.
It's important to realise that, although they frequently appear together, IDENTITY and PRIMARY KEY are two orthogonal concepts1. So, to the question as asked, the answer is no - as IDENTITY column will quite happily provide a value that has already been used in the same column:
set nocount on
go
create table II (
ID int IDENTITY(1,1) not null,
Value varchar(10) not null
)
insert into II(Value) values ('abc'),('def')
set identity_insert II on
insert into II(ID,Value) values (6,'ghi')
set identity_insert II off
select * from II
insert into II(Value) values ('jkl')
select * from II
GO
dbcc checkident (II, RESEED, 5);
GO
insert into II(Value) values ('mno'),('pqr')
select * from II
Results:
ID Value
----------- ----------
1 abc
2 def
6 ghi
ID Value
----------- ----------
1 abc
2 def
6 ghi
7 jkl
Checking identity information: current identity value '7'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
ID Value
----------- ----------
1 abc
2 def
6 ghi
7 jkl
6 mno
7 pqr
Whereas a PRIMARY KEY will complain if you attempt to insert a duplicate value:
create table III (
ID int IDENTITY(1,1) not null PRIMARY KEY,
Value varchar(10) not null
)
insert into III(Value) values ('abc'),('def')
set identity_insert III on
insert into III(ID,Value) values (6,'ghi')
set identity_insert III off
select * from III
insert into III(Value) values ('jkl')
select * from III
GO
dbcc checkident (III, RESEED, 5);
GO
insert into III(Value) values ('mno'),('pqr')
select * from III
go
(The only different from the previous script is the table name and the addition of PRIMARY KEY)
Results:
ID Value
----------- ----------
1 abc
2 def
6 ghi
ID Value
----------- ----------
1 abc
2 def
6 ghi
7 jkl
Checking identity information: current identity value '7'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'PK__III__3214EC27FCCBBCB7'. Cannot insert duplicate key in object 'dbo.III'. The duplicate key value is (6).
The statement has been terminated.
ID Value
----------- ----------
1 abc
2 def
6 ghi
7 jkl
1 The third concept that is frequently conflated with these two is that of the Clustered Index. It's perfectly possible for a table to have a Primary Key, an Identity Column and a Clustered Index that have no columns in common.

Primary key (two columns) identity increment

I have two columns in my primary key (id, type), id is identity and type is foreign key.
I want to set seed for id column like following:
id type
10000 1
10001 1
10000 2
10001 2
10002 1
10002 2
10000 3
I could do this from code (or dml), but wonder is it possible in ddl or SqlServer table properties?
An id column increments by 1 for each row. There is no way to have it repeat. Any reason why you can't just have the identifier column be the pk for the table? You may have to resort to using a trigger to do this.
Microsoft SQL Server does not allow you to add or alter an Identity on an existing column via TSQL very easily. To change the original seed value and reseed any existing rows, you must drop the identity column and recreate it specifying the new seed value. When the table contains data, the identity numbers are added to the existing rows with the specified seed and increment values.

Resources