Duplicate a row in SQL? - sql

OK I have a table that has two columns, userID and courseID. It is used to assign training courses to a user. It looks like this:
userid courseid
0 1
0 3
0 6
1 1
1 4
1 5
so user 0 is assigned to courses 1,3,6 and user 1 is assigned to 1, 4 5
anyways I need to take every user that is assigned to 6 and create a new row that has that userid and courseid 11, basically assigning every user who is currently assigned to 6 to also be assigned to 11
for some reason (I did not create this database) both rows are marked as primary keys, and some statements I have tried have thrown an error because of this, what the heck is the deal?
oh maybe it is because there are a few users that are already assigned to 11 so it is choking on those maybe?
please help

Insert Into TableName (userID, courseID)
Select userID, 11 From TableName Where courseID=6;
Also, I'm a bit confused by your comment that both are primary keys. Both rows can be part of the primary key or both can be Unique keys but they cannot both be a primary key. As far as errors go, it is probably because the query tried to insert rows that were duplicates of already existing rows. To eliminate this possibility you could do this:
Insert Into TableName (userID, courseID)
Select userID, 11 From TableName Where courseID=6
AND (userID not in (Select userID From TableName Where courseID=11))
Depending on your database this could work too:
INSERT OR IGNORE INTO TableName (userID, courseID)
SELECT userID, 11 FROM TableName WHERE courseID=6;
Anyway, there you go.

insert into TableName (userId, courseId)
select userId, 11
from TableName
where courseId = 6
and not exists (
select 1
from TableName nested
where nested.userId = TableName.UserId
and nested.courseId = 11
)
Selects all users that are assigned to courseId 6 but are not yet assigned to courseId 11 and inserts a new record into the table for them for courseId 11.

This should help:
INSERT
INTO [table]
(
userid,
courseid
)
SELECT userid,
11
FROM [table]
WHERE courseid = 6
AND userid NOT IN
(SELECT userid
FROM [table]
WHERE courseid = 11
);
This will select all users in course 6 not in course 11 and add them with course 11 to the table.

Related

Own id for every unique name in the table?

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

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.

SQL 2008: Insert multiple rows based on specific criteria

I am trying to clone user permissions. The permissions are driven from a table with only 2 columns, userid and groupid. Both are foreign keys.
Is it possible to insert multiple rows based on criteria? Let's say:
USERID GROUPID
1 A
1 B
1 C
1 D
I would like to insert rows to give USER 2 the same GROUPS as USER 1.
Does this get me close?
INSERT INTO ide_usergroup_assoc (userid, groupid)
VALUES ('USERID I PROVIDE', (SELECT ide_usergroup_assoc.groupid from ide_usergroup_assoc WHERE ide_usergroup_assoc.userid = 'USERID TO BE CLONED'))
insert into ide_usergroup_assoc (userid, groupid)
select 2, groupid
from ide_usergroup_assoc
where userid = 1

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