Insert multiple records - sql

I have the SQL below. SQL return a Users.Id which are not found in Order table. I need to create Insert SQL and insert default order for these users. How to do that?
SELECT Id
FROM [User] WHERE Id NOT IN (SELECT UserId FROM dbo.[Order])
Order table columns are
Id , -- Random Number
UserId , -- Id from Select above
FirstName ,
LastName ,
Credits

Assuming dbo.[User] has the FirstName, LastName and Credits columns you can do it like this:
Insert Into dbo.[Order] (UserId, FirstName, LastName, Credits)
SELECT u.Id, u.FirstName, u.LastName, u.Credits
FROM [User] u WHERE u.Id NOT IN (SELECT o.UserId FROM dbo.[Order] o)
You can see here for another example. You might understand it :)
To generate the Unique Id use the Identity Property.

Related

Join 2 tables on foreign key while using count() in SQL

So I have two tables: Please see the ER diagram here
I want to use SELECT to create one table with "name" from the USER table, "id" as the foreign key for the two tables, and the count of friend_id as the number of friends each user has.
Here is my code:
SELECT name, id, (SELECT count(friend_id) as number
FROM friend
GROUP BY user_id)
FROM user
ORDER BY number DESC
I'm wondering what's the problem with these lines. Thank you!
You can use a subquery to calculate the count.
SELECT name, id, COALESCE(f.Count, 0) AS friend_count
FROM user u
LEFT JOIN (
SELECT user_id, COUNT(DISTINCT friend_id) AS Count
FROM friend
GROUP BY user_id
) f ON f.user_id = u.id
ORDER BY friend_count DESC
I used a LEFT JOIN so that if a user doesn't have a row in friend, it will still return a row with a friend count of 0 (thanks to COALESCE). I also added a DISTINCT so that if the friend has duplicates the friend is counted only one, might not be necessary especially if you have a UNIQUE INDEX setup on columns user_id, friend_id
Just add where to find only one id and remove group by because you have only one id for one or more friends as your diagram says.
SELECT name, id, (SELECT count(friend_id) as number
FROM friend
WHERE user_id = user.id)
FROM user
ORDER BY number DESC
I think this will be correct for you puprose
CREATE TABLE #user(
id VARCHAR(22),
[name] VARCHAR(255),
)
CREATE TABLE #friend(
user_id VARCHAR(22),
friend_id VARCHAR(22)
)
SELECT name, id, (SELECT COALESCE(COUNT(friend_id), 0)
FROM #friend f
WHERE f.user_id = u.id
GROUP BY user_id) as number
FROM #user u
ORDER BY number DESC
--Same query with join:
SELECT u.[name], u.id, COALESCE(COUNT(f.friend_id),0) number
FROM #user u
LEFT JOIN #friend f ON f.user_id = u.id
GROUP BY u.[name], u.id
ORDER BY number

Select Statement in SQL inheritance

CREATE TABLE User(
UserID int primary key,
Name varchar,
type int
);
CREATE TABLE Student(
UserID int primary key references User(UserID),
marks int
);
CREATE TABLE Lecture(
UserID int primary key references User(UserID),
salary int
);
Can someone help with with select statement for Student or lecture.
Both Lecture and Student tables are inheriting from User table,So I need to know how insert data and select data from these tables.
To query the tables, this would work:
SELECT u.[Name]
, s.marks
, l.salary
FROM [User] u
INNER JOIN Student s
ON u.UserId = s.UserId
INNER JOIN Lecture l
ON u.UserId = l.UserId;
However, if there are no records in the Student / Lecture tables yet, you should use LEFT Join instead.
As for inserting the data, you would need to use SCOPE_IDENTITY().
Insert into [User] (Name) values ('Melvin')
Get the identity of the UserId
DECLARE #userId INT;
SELECT #userId = SCOPE_IDENTITY ();
INSERT INTO Student
(
UserID
, Marks
)
VALUES
(userId, 5);
Update: Just noticed this was SQL Lite, which I'm not so familiar with, but it looks like it supports last_insert_rowid() instead of SCOPE_IDENTITY (), but you should get the gist of it.
If you want to select Student X:
SELECT *
FROM Student
WHERE UserID = X
If you want to select all Students and their User data, you'll want something like:
SELECT *
FROM User
JOIN Student ON User.UserID = Student.UserID
I don't understand your question but I think you need something like that
select Name, marks
from User as u, Student as s
inner join u.UserID == s.UserID;

Insert values from one table to another table and other additional values

I have two tables Users and Friends. I want to copy two ID s for different users from Users table where their names already provided by C# code behind and put them into Friends table with their status column to be stored in one row at Friends table. Here is the query I made:
#id uniqueidentifier,
#username nvarchar(50),
#friendname nvarchar(50),
#friendstatus int
AS
INSERT INTO Friends (MYID,FriendId,ID,FriendStatus)
SELECT Users.ID,Users.ID,#id,#friendstatus
From Users cross join Friends as Friends_1
WHERE (Friends_1.MyID IN
(SELECT ID
FROM Users AS Users_1
WHERE (UserName IN (#username))))
AND (Friends_1.FriendId IN
(SELECT ID
FROM Users AS Users_1
WHERE (UserName IN (#friendname))))
I think this is what you are looking for
INSERT INTO Friends (MYID,FriendId,ID,FriendStatus)
SELECT Users.ID, Users.ID, #id, #friendstatus
From Users
inner join Friends as Friends_1 ON Users.ID = Friends_1.MyID
OR Users.ID = Friends_1.FriendId
WHERE UserName IN (#username, #friendname)
I think you can do it with a simple query like this:
insert into Friends (ID, MYID, FriendId, FriendStatus)
select
newid() ID, -- you can generate a new ID in SQL Server
-- #id ID -- if you generate ID in your c# code:
u1.ID MYID,
u2.ID FriendId,
#friendstatus FriendStatus
from
users u1
cross join
users u2
where
u1.UserName = #username
and
u2.UserName = #friendname;

SQL find records with duplicate email and date of birth

I'm trying to write a query to find any duplicate records in my database. I want to find all records (not the count) where the EmailAddress AND DateofBirth (both columns) already exist on another record.
Account tbl contains the EmailAddress.
User tbl contains the DateOfBirth
Join on AccountID
The following query selects records where the EmailAddress exists in another record OR the DateOfBirth exists in another record, but I'm unable to combine the two conditions. If I'm correct so far, the 'and' on line 7 acts more like an 'or' in my case..?
select a.AccountName, a.EmailAddress, u.DateOfBirth from Account as a
join [User] as u
on a.AccountID = u.AccountID
where a.EmailAddress in (
select EmailAddress from Account group by EmailAddress having count(*) > 1
)
and
DateOfBirth in(
select DateOfBirth from [User] group by DateOfBirth having count(*) > 1
)
order by u.DateOfBirth, a.EmailAddress
For example, this may produce 50 records. If I look through them, I find 5 records all with the matching EmailAddress, however only 4 of them have the same DateOfBirth. The 5th record is displaying due to another record in the database with the same DateOfBirth but different EmailAddress.
I'd like to find only those records who have both the matching email and dob.
Thanks as always, please ask if you require a further description.
Regards
Json
Using your approach, you can use exists:
select a.AccountName, a.EmailAddress, u.DateOfBirth
from Account as a join
[User] as u
on a.AccountID = u.AccountID
where exists (select EmailAddress
from Account a2 join
[User] u2
on a.AccountID = u.AccountID
where a2.EmailAddress = a.EmailAddress and
u2.DateOfBirth = u.DateOfBirth
group by EmailAddress
having count(*) > 1
)
order by u.DateOfBirth, a.EmailAddress;
A better way is to use window/analytic functions:
select AccountName, EmailAddress, DateOfBirth
from (select a.AccountName, a.EmailAddress, u.DateOfBirth,
count(*) over (partition by a.EmailAddress, u.DateOfBirth) as cnt
from Account as a join
[User] as u
on a.AccountID = u.AccountID
) ua
where cnt > 1
order by DateOfBirth, EmailAddress;
Join the two tables on the account id.
Group by email and date
Show only those entries which have count(*) > 1 (using the HAVING expression).
In MySQL (I have no MS SQL server available at the moment), this can be done with:
SELECT * FROM a JOIN b ON a.account = b.account
GROUP BY email, birth
HAVING count(*) > 1;
Where I used the following commands to setup the tables a and b:
create table a (
account int primary key auto_increment,
email text
);
create table b (
account int,
birth date,
constraint foreign key (account) references a (account)
);
insert into a (email) values ("email1"), ("email1"), ("email2"), ("email2");
insert into b values (1, "2000-01-01"), (2, "2000-01-01"), (3, "2000-01-01"), (4, "2000-01-02");

Add rows from a table where they're not in the other table

I have the following tables:
Contacts
contact_id, contact_name, etc.
assigned_lists
contact_id, list_id
Each contact can be associated with more than 1 list, which is stored in the assigned_lists column.
I have a lot of contacts who are not associated with any lists. How would I insert all the contact_id's that are not associated with a list into assigned_lists?
Try with:
INSERT INTO assigned_lists (contact_id, list_id)
SELECT contact_id, 24
FROM Contacts
WHERE contact_id NOT IN (
SELECT DISTINCT contact_id
FROM assigned_lists
)
INSERT INTO assigned_lists (contact_id, list_id)
SELECT contact_id, #yourNewListID
FROM Contacts
WHERE contact_id NOT IN (SELECT contact_id FROM assigned_lists)
SQL Fiddle Example: http://sqlfiddle.com/#!3/d59d1e/1
you can try the below
INSERT INTO assigned_lists (contact_id, list_id)
SELECT contact_id, list_id = 1234
FROM Contacts C
WHERE NOT EXISTS (SELECT 1 FROM assigned_lists A WHERE A.contact_id = C.contact_id )
remember, not exists clause has a performance edge over not in clause.
A detailed explanation about the same can be found here NOT IN vs NOT EXISTS