Unique index in already existing database table - sql

I am trying to add a new unique index on one of my database tables in SQL Server 2008. This is an existing table and the column where I want the unique index already has some duplicate values.
Can I set up a unique index for that column? If so, how?

You can't set this column up with a UNIQUE index if the table already has duplicate values, unless you remove the records containing the duplicate values for that column. This goes to the definition of UNIQUE.

First you are gonna need to delete the duplicate values on your column and then you can create a unique index on it. So lets assume your table has 2 columns, id and column1. To delete duplicate values you need to choose one, it can be random or with some order. So it would be like this:
WITH CTE AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY column1 ORDER BY Id) Corr
FROM YourTable
)
DELETE FROM CTE
WHERE Corr > 1
CREATE UNIQUE INDEX I_Unique ON YourTable(Column1)

No as the name suggest, Unique Index which says key has to be unique. So you cant
See this

If the column already has duplicate values then I would recommend you create a unique composite key instead.
e.g.
So, to handle that issue with this table design, you need to create a unique constraint on the table CustomerID/ProductID columns:
create unique index cust_products_unique on CustomerProducts (CustomerID, ProductID)
So that in essence a combination of fields ensures that the index is unique.
Regards

May not have been true in SQL Server 2008, however you can use Management Studio to do this in later versions such as 2014.
Right click your table
Choose Design
Expand "Identity Specification" and set (is Identity) to Yes
Save

Related

How to ensure that there are no duplicates in field? MS SQL Server 2014

I have the following table:
Customer (Id, Name, employeeID)
The table is already created and is empty, I don't want to remove duplicate data, all I want is to ALTER the table to ensure that there will be no duplicate data
I want to use ALTER and ensure that there are no duplicates in employeeID.
Will
ALTER TABLE Customers
UNIQUE(employeeID)
ADD CONSTRAINT
Is there a better way?
Adding a unique constraint will ensure that no duplicate entries will be added in future:
ALTER TABLE Customers
ADD CONSTRAINT choose_a_name_for_the_constraint UNIQUE (EmployeeID);
You had it basically right, just a bit of a keyword order problem..
If you're working with SQLS, consider also that trivial operations like this can be done via the GUI in SSMS, and it will guide the process. You can also get it to turn the changes into scripts for you by right clicking the table and choosing "Script Table As..." so you can use them elsewhere
From my understanding, I create Unique Index as follows,
create table unicondtional (
i int identity (1,1)
, j int
)
insert into unicondtional values (1), (1)
select * from unicondtional
-- assume 'unicondtional' is table like what you have, so far.
CREATE UNIQUE NONCLUSTERED INDEX unique_with_condition ON unicondtional
(
j
)
WHERE (i > 2) -- max (i)
-- create unique index with condition.
-- from the 'where' clause, we say that, Index should be ensure the unique value insertion.
insert into unicondtional values (1), (2), (3) -- See the Note.
-- successful insert.
select * from unicondtional
insert into unicondtional values (2)
-- due to the Unique Index, duplicate is not allowed by the Index.
update unicondtional
set j = 3
where j = 1
-- before the Index(On the first two rows), duplicates are exist.
select * from unicondtional
So, you don't need to delete the existing duplicate records.
Note: After the Index, if you consider the 1 as duplicate, then you go with Trigger instead of Unique Index.
Since your table is empty, you can directly run
ALTER TABLE Customers
ADD CONSTRAINT UQ_EmployeeID UNIQUE(EmployeeId);
That will ensure there is no duplicate EmployeeId can be added in that table.
But if there is some data in the table and there is already a duplicate EmployeeId you will get an error message
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'Customers' and the index name 'UQ_EmployeeId'. The duplicate key value is ("DuplicateValueHere").
For your question
Is there a better way?
You already have the better way to prevent inserting duplicates.
See
Create Unique Constraints
and
ALTER TABLE (Transact-SQL)

Select row query given table name and primary key in Oracle?

So after googling this simple question, I could have not find an answer anywhere. I only have very basic database knowledge, and I need a query in Oracle to properly select a row given a table name and a primary key. Most examples I have found all find rows based of a row number or rowID (is that the same as primary key?).
Any help on this would be greatly appreciated.
Do you have the primary key column and the value you want to query? Where or what exactly did you search for? This is a very basic SELECT statement in any relational database:
SELECT *
FROM table_name
WHERE primary_key_column = primary_key_value
Unless, of course, I didn't understand the question.
A primary key is a unique identifier for a row in a table. Each row will have a primary key that is different from all other rows. This key can be one value, such as a rowID, or it can be a composite value (multiple columns used as a primary key because there may not be a need for an extra column only to store a rowID).
#tilley31 above shows a great example of how to search for a specific row in a table. If the primary key was composite;
SELECT *
FROM table_name
WHERE primary_key_column1 = primary_key_value1
AND primary_key_column2 = primary_key_value2
ROWID is a pseudocolumn that returns the address of a row and is usually unique, exception being where more than one table is stored in a same cluster then those tables rows can share the same rowid. ROWID is implicitly given by the oracle to rows.
Primary key uniquely identifies a row at a table level and is created by the user who created the table.
Getting the ROWID of a Row
SELECT ROWID,FIELDNAME FROM ABC;
Getting the PRIMARY Key of a table
SELECT * FROM USER_CONSTRAINTS WHERE TABLE_NAME='YOUR_TABLENAME'
AND CONSTRAINT_TYPE='P';
I guess you are intent to dynamically choose table and where clauses in query (?)
If this is what you want to do then answer is No. Its not possible just through query. You could achieve it through pl/sql. and if you must have this as a query consider using a table function like below -
SELECT * FROM TABLE(func('TABLE_NAME','WHERE_CONDITION'))
Check out this link: https://oracle-base.com/articles/misc/pipelined-table-functions
Again this requires you to have preset output columns (COLUMN1, COLUMN2 etc). You will not be able to select exact column names from table.
Overall this is going to be messy.

How to add not null unique column to existing table

Is there any way to simply add not null unique column to existing table. Something like default = 1++ ? Or simply add unique column?
I tried to add column and then put unique contrain but MS SQL says that:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name (...) The duplicate key value is ( < NULL > ).
Any way to simply add column to existing working table with unique constrain? Should MS SQL really think that null IS a value?
Add not null column with some default.
Update column to be a sequential integers (see row_number() function)
Add UNIQUE constraint or UNIQUE index over new column
You can add IDENTITY column to a table (but from question it is not clear if you need it or not).
IDENTITY is all you need:
ALTER TABLE TestTable
ADD ID INT IDENTITY(1, 1)
If you want an autonumber, you can add an identity.
If you need to populate the values yourself, you add the column allowing nulls, update the values, check to make sure they are unique and that there are no nulls, then add the unique constraint and trhe not null property. It is best to do this during a maintenance window when no one else would be changing data in that table.

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 to insert duplicate rows in SQLite with a unique ID?

This seems simple enough: I want to duplicate a row in a SQLite table:
INSERT INTO table SELECT * FROM table WHERE rowId=5;
If there were no explicit unique column declarations, the statement would work, but the table's first column is declared rowID INTEGER NOT NULL PRIMARY KEY. Is there any way to create a simple statement like the one above that works without knowing the schema of the table (aside from the first column)?
This can be done using * syntax without having to know the schema of the table (other than the name of the primary key). The trick is to create a temporary table using the "CREATE TABLE AS" syntax.
In this example I assume that there is an existing, populated, table called "src" with an INTEGER PRIMARY KEY called "id", as well as several other columns. To duplicate the rows of "src", use the following SQL in SQLite3:
CREATE TEMPORARY TABLE tmp AS SELECT * FROM src;
UPDATE tmp SET id = NULL;
INSERT INTO src SELECT * FROM tmp;
DROP TABLE tmp;
The above example duplicates all rows of the table "src". To only duplicate a desired row, simply add a WHERE clause to the first line. This example works because the table "tmp" has no primary key constraint, but "src" does. Inserting NULL primary keys into src causes them to be given auto-generated values.
From the sqlite documentation: http://www.sqlite.org/lang_createtable.html
A "CREATE TABLE ... AS SELECT" statement creates and populates a database table based on the results of a SELECT statement. A table created using CREATE TABLE AS has no PRIMARY KEY and no constraints of any kind.
If you want to get really fancy, you can add a trigger that updates a third table which maps old primary keys to newly generated primary keys.
No. You need to know the schema of the table to write the insert statement properly.
You need to be able to write the statement in the form of:
insert into Table (column1, column2, column3)
select column1, column2, column3
from OtherTable
where rowId = 5
Well, since I was unable to do this the way I wanted, I resorted to using the implicit row id, which handily enough has the same name as the rowId column I defined explicitly, so now I can use the query I had in the question, and it will insert all the data with a new rowId. To keep the rest of the program working, I just changed SELECT * FROM table to SELECT rowId,* FROM table and everything's fine.
Absolutely no way to do this. Primary Key declaration implies this field is unique. You can't have a non unique PK. There is no way to create a row with existing PK in the same table.