Own id for every unique name in the table? - sql

Is it possible to make a table that has like auto-incrementing id's for every unique name that I make in the table?
For example:
ID NAME_ID NAME
----------------------
1 1 John
2 1 John
3 1 John
4 2 Mary
5 2 Mary
6 3 Sarah
7 4 Lucas
and so on.

Use the window function rank() to get a unique id per name. Or dense_rank() to get the same without gaps:
SELECT id, dense_rank() OVER (ORDER BY name) AS name_id, name
FROM tbl;
I would advise not to write that redundant information to your table. You can generate that number on the fly. Or you shouldn't store name redundantly in that table, name would typically live in another table, with name_id as PRIMARY KEY.
Then you have a "names" table and run "SELECT or INSERT" there to get a unique name_id for every new entry in the main table. See:
Is SELECT or INSERT in a function prone to race conditions?

First add the column to the table.
ALTER TABLE yourtable
ADD [UID] INT NULL;
``
ALTER TABLE yourtable
ADD constraint fk_yourtable_uid_id foreign key ([UID]) references yourtable([Serial]);
Then you can update the UID with the minimum Serial ID per Name.
UPDATE t
SET [UID] = q.[UID]
FROM yourtable t
JOIN
(
SELECT Name, MIN([Serial]) AS [UID]
FROM yourtable
GROUP BY Name
) q ON q.Name = t.Name
WHERE (t.[UID] IS NULL OR t.[UID] != q.[UID]) -- Repeatability

Related

Update multiple rows based on unique values in another column in same table

I have a table with two columns. The table columns are name, and companyID, and they are in the [dbo].[Suppliers] table.
I need to update the CompanyID values ONLY for Unique Names.
UPDATE [dbo].[Suppliers]
SET CompanyId = 46
WHERE Name IN
(
SELECT DISTINCT Name
FROM [dbo].[Suppliers]
);
i.e.
Trying to get this
Name CompanyID
A 5
B 5
C 5
A 5
To look like:
Name CompanyID
A 6
B 6
C 6
A 5
Unfortunately, my query above is not doing the trick.
Appreciate any and all help. Thanks.
You can use a Common Table Expression to add a row number to each name, then update that CTE but specify only the first row for each name...
WITH
uniquely_identified AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY name ORDER BY companyID) AS name_row_id,
*
FROM
[dbo].[Suppliers]
)
UPDATE
uniquely_identified
SET
CompanyId = 46
WHERE
name_row_id = 1
;
Example: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=4b5eba30b3bed71216ec678e9cffa6b9

How to delete values from first table by using name of the second sql

I have a table groups
group_id | name_group
1 ISI
2 IZI
And a table students
id | first_name | last_name | group_id
6 Bob Surname1 1
17 John Surname2 2
How can I delete all information from student table by using groups.name?
i.e. I need query which select all students with the same group_id which is equivalent to name.
group_id 1 = 'ISI'
group_id 2 = 'IZI'
And a query must delete exactly by name.
You can use this query
Delete from Students where group_id=(Select group_id from groups where name_group='ISI');
This all the records with the group_id of 1 (via group_name='ISi').
There are different ways. A simple one, could be selecting the Id of the group and deleting from there. Example:
DECLARE
#name as nvarchar(20) = 'myName'
-- we display the data just for check
SELECT s.*, g.group_id
FROM students s ON g.group_id = s.group_id
WHERE g.name_group = #name
--we look the group id and delete the matches with students
DELETE
FROM students
WHERE group_id in (SELECT group_id FROM groups WHERE name_group = #name)
PD: This basic approach could work on both: MySQL and MSSQL.

How can I insert records from a table to another table order by the specific column value?

Does anyone know how can I insert records from a table to another table order by the specific column value?
For Example:
I have the following table:
tableA:
record_id int,
name varchar(100),
nickname(100),
chain_id int (PK),
chain_n int,
count int,
create_date datetime
tableB:
record_id int,
name varchar(100),
nickname(100),
chain_id int (PK),
chain_n int,
create_date datetime
I have the following value for tableA:
record_id name nickname chain_id chain_n count create_date
1 Test One 1 1 2 2013-06-06
2 Test Two 2 1 5 2013-06-06
3 Test Three 3 1 3 2013-06-06
I using the following scrip to insert the data into thableB
INSERT INTO tableB
(
record_id,
name,
nickname,
chain_id,
chain_n,
create_date
)
SELECT
(
record_id,
name,
nickname,
chain_id,
chain_n,
create_date
)
FROM tableA
ORDER BY count DESC
I expecting the data will insert into tableB like the following:
record_id name nickname chain_id chain_n create_date
2 Test Two 2 1 2013-06-06
3 Test Three 3 1 2013-06-06
1 Test One 1 1 2013-06-06
However, the result was as following still order by the chain_id
record_id name nickname chain_id chain_n create_date
1 Test One 1 1 2013-06-06
2 Test Two 2 1 2013-06-06
3 Test Three 3 1 2013-06-06
Does anyone know how can manage to insert the records order by the count instead
It seems that record_id is your primary key and thus default ordering is done by that. That's why your output is same as in tableA. Just use ORDER BY in SELECT clause for tableB.
Inserting records into a table in particular order doesn't make much sense to me becuase ORDER BY doesn't actually influence the way the data is written to your drive. All records will be inserted in the order of your clustered index. In any case if you want to query data from a table ordered by some field you should explicitly state it in the ORDER BY clause even if you want your data ordered by clustered index columns. Although all data is meant to be ordered by clustered index by default it's still up to SQL Server engine to define the best execution plan and change the order if required if you don't specify it explicitly in the ORDER BY clause.

How to delete only recode from table?

I have one table in my database
Id Name
-------------------------
1 1 a
2 1 a
3 1 a
4 2 b
5 2 b
6 2 b
This my database table it's has 6 rows and 2 columns Id and Name
In this table field Id is not a primary key and i want to delete 2 number row from my by id field table
After Delete 2 row of table i want output like this
Id Name
-------------------------
1 1 a
3 1 a
4 2 b
5 2 b
6 2 b
Is it possible?
Your ID should be unique but here is the sql to delete all IDs that are 2.
Delete FROM table WHERE table.Id=2;
Replace 'table' with your table name.
Edit:
It appears like you want to delete the second result. I don't know why but here is the sql:
with rn AS
(
SELECT *, rn = ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM table
)
DELETE
FROM rn
WHERE rn = 2
There must be some criteria in a table by which you could identify its rows. That is the primary key. How do know that the order of the rows stays the same? Your table is not even sortable, I mean you can't be sure that the same SELECT statement returns rows in the same order.
That's why I'd answer that you CAN'T delete only and exactly record number two, cause you have no order in your table. And one SELECT would result in different rows on the 2nd position.
If the Id field must have such values, probably you could add a surrogate primary key.

SQL Server table - Update Order by

I have a SQL Server table with fields: id, city, country. I imported this table from Excel file, everything is imported successfully, but id field is not ordered by number. The tool I use imported the rows in some random number.
What kind of Update command I should use from SQL Server Management Studio Express to re-order my ids?
Do you have a primary key and a clustered index on your table? If not, id is a good candidate for a primary key and when you create that the primary key it will be the clustered index.
Assuming this is your table
create table CityCountry(id int, city varchar(10), country varchar(10))
And you add data like this.
insert into CityCountry values (2, '2', '')
insert into CityCountry values (1, '1', '')
insert into CityCountry values (4, '4', '')
insert into CityCountry values (3, '3', '')
The output of select * from CityCountry will be
id city country
----------- ---------- ----------
2 2
1 1
4 4
3 3
A column that is primary key can not accept null values so first you have to do
alter table CityCountry alter column id int not null
Then you can add the primary key
alter table CityCountry add primary key (id)
When you do select * from CityCountry now you get
id city country
----------- ---------- ----------
1 1
2 2
3 3
4 4
Just use the order by part of the select statement to order them.
If I understood you correctly, you want all the ids to have consecutive numbers 1,2,3,4...
Image your table contents is:
select *
from yourTable
id city country
----------- ---------- ----------
1 Madrid Spain
3 Lisbon Portugal
7 Moscow Russia
10 Brasilia Brazil
(4 row(s) affected)
To reorder the ids, just run this:
declare #counter int = 0
update yourTable
set #counter = id = #counter + 1
(4 row(s) affected)
You can now check, that indeed all the ids are reordered:
select *
from yourTable
id city country
----------- ---------- ----------
1 Madrid Spain
2 Lisbon Portugal
3 Moscow Russia
4 Brasilia Brazil
(4 row(s) affected)
However, you need to be careful with this. If some table has a Foreign key to this id column, then you need first to disable that FK, update this table, update the values in other tables that have FK's pointing to yourTable finally enable again the FKs
First, I think you may have some misconceptions about the purpose of the Id column. The Id column is probably a surrogate key; i.e. an arbitrary value that is unique and non-null that is never shown to the user. Thus, it should not be implied to have any inherit meaning or sequence. In fact, you should always have another column or columns that are marked as being unique to represent a "business key" or a set of values that are unique to the user. In your case, city, country should probably be unique (although you will likely need to add province or state as it is common to have the same city exist in the same country multiple times.)
Now, that said, it is possible to re-sequence your Ids if the following are true:
The Id column is not an identity column. Since this was from an import, I'm going to guess this is true.
There does not exist a relationship to the table where Cascade Update is not enabled.
You are using SQL Express 2005 or later:
Update MyTable
Set Id = T2.NewId
From (
Select Id
, Row_Number() Over ( Order By Id ) As NewId
From MyTable
) As T1
Join MyTable As T2
On T2.Id = T1.Id