SQL INSERT statement for TWO TABLES at time with INNER JOIN - sql

I have two tables hello and login_table and below is their structure
user_info
-------
some_id | name | address
login_table
-------
id | username | password
some_id and id are autoincrement indexes.
Now how can i use INSERT statement with INNER JOIN in SQL
at present, i want add below data with same some_id and id
`name` = John
`address` = wall street
`username` = john123
`password` = passw123
below code shows, what i have tried so far.
insert into login_table lt
INNER JOIN user_info ui ON ui.some_id = lt.id
(ui.name, ui.address, lt.username, lt.password)
values
('John', 'wall street', 'john123', 'passw123')
And this is not the one value, i want to add more than one value at a time.. how can i achieve.
thanks for help.

If you need to perform the two INSERT operations atomically, use a transaction:
START TRANSACTION;
INSERT INTO login_table (username, password) VALUES ('john123', 'passw123');
INSERT INTO user_info (name, address) VALUES ('John', 'wall street');
COMMIT;
N.B. Your storage engine must support transactions for this to work (e.g. InnoDB).
To insert multiple values into a table at once, use the multiple rows form of INSERT. As stated in the manual:
INSERT statements that use VALUES syntax can insert multiple rows. To do this, include multiple lists of column values, each enclosed within parentheses and separated by commas. Example:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
The values list for each row must be enclosed within parentheses. The following statement is illegal because the number of values in the list does not match the number of column names:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);
VALUE is a synonym for VALUES in this context. Neither implies anything about the number of values lists, and either may be used whether there is a single values list or multiple lists.

Insert to two tables is impossible. The second part of your question is possible: you can insert multiple rows in one statement like this:
insert into some_table(col1, col2) values (1,2), (3,4), (5,6);

USE [ERPDb]
GO
INSERT INTO [AAA].[UserRole] ([UserId], [RoleId])
SELECT u.Id, (SELECT Id FROM [AAA].[Role] WHERE Title = 'Employee') FROM [AAA].[User] u
INNER JOIN [dbo].[BaseDealer] bd ON u.Id = bd.Id
WHERE bd.DealerType = 0
GO

Related

Foreach insert statement based on where clause

I have a scenario where I have thousands of Ids (1-1000), I need to insert each of these Ids once into a table with another record.
For example, UserCars - has columns CarId and UserId
I want to INSERT each user in my Id WHERE clause against CarId 1.
INSERT INTO [dbo].[UserCars]
([CarId]
,[UserId])
VALUES
(
1,
**My list of Ids**
)
I'm just not sure of the syntax for running this kind of insert or if it is at all possible.
As you write in the comments that my list of Ids is coming from another table, you can simply use select into with a select clause
See this for more information
insert into UserCars (CarID, UserID)
select CarID, UserID
from othertable
In the select part you can use joins and whatever you need, complex queries are allowed as long as the columns in the result match the columns (CarID, UserID)
or even this to keep up with your example
insert into UserCars (CarID, UserID)
select 1, UserID
from dbo.User
if your data exists on a file, you can use BULK INSERT command, for example:
BULK INSERT UserCars
FROM '\\path\to\your\folder\users-cars.csv';
Just make sure to have the same columns structure both in the file and in the table (e.g. CarId,UserId).
Otherwise, follow #GuidoG comment to insert your data from another table:
insert into UserCars (CarID, UserID) select CarID, UserID from othertable

Insert into 2 tables with single SQL statement instead of loop

I have to insert data in provonance of several table which itself comes from csv (COPY).
Before I used a LOOP in a function to enter the data. I want to simplify the thing for the sake of maintainability and speed.
I need to insert data into a description table, which serves as both the title and description (and multi language).
Previously my code was as follows (extract from the loop):
insert into description (label, lang_id, poi_id,date_dernier_update, date_enregistrementbdd, date_derniere_lecture) values (label, lang_id, poi_id, now(), now(), now()) RETURNING id INTO _retour_id_titre;
insert into poi_titre_poi (poi_id, titre_poi_id, titre_poi_key) values (poi_id, _retour_id_titre, label_lang);
But now I can't:
with rows as (
insert into description (label, lang_id, poi_id)
select rdfslabelfrs, '1', (select id from poi where uri_id = csv_poi_rdf_fr.poi) as toto from csv_poi_rdf_fr RETURNING id
)
insert into poi_titre_poi (poi_id, titre_poi_id, titre_poi_key)
select description.poi_id, id , 'fr'
FROM description;
In fact, I cannot insert the 'poi_id' in the 'poi_titre_poi' table which corresponds to the one which was inserted in the description table.
I get this error message:
ERROR: more than one row returned by a subquery used as an expression
État SQL : 21000
Can I make this work, or do I need to loop?
Filling in missing bits with assumptions, it could work like this:
WITH description_insert AS (
INSERT INTO description
(label , lang_id, poi_id)
SELECT c.rdfslabelfrs, 1 , p.id
FROM csv_poi_rdf_fr c
JOIN poi p ON p.uri_id = c.poi
RETURNING poi_id, id
)
INSERT INTO poi_titre_poi (poi_id, titre_poi_id, titre_poi_key)
SELECT d.poi_id, d.id , 'fr'
FROM description_insert d;
Related:
PostgreSQL multi INSERT...RETURNING with multiple columns
Insert data in 3 tables at a time using Postgres
Get Id from a conditional INSERT

SQL Server How to insert multiple values while excluding repeating values

I'm developing a query for a program where user has to enter one or multiple multiple values into a DB table.
The issue with the query is when you try to insert multiples values it could be that some of those values are repeated in the tables and the warning will only display one repeated value at a time and that might be a problem when you are working with a 1000+ values.
Error Message:
Cannot insert duplicate key row in object 'ItemWebCategory' with unique index 'IX_StyleID_WebCategoryID'. The duplicate key value is (1109068, 99999).
Query
insert into ItemWebCategory (Style_id,WebCategoryID)
select distinct Style_id,WebCategoryID = '99999'
from ItemCategory
where style_id in ('1109068','168175', '68435', '545457', '69189')
Question
How can I modify the query so it may skip/exclude all repeating values and only insert the values that do no exist on the table?
Try something like this:
INSERT INTO ItemWebCategory ( Style_id, WebCategoryID )
SELECT DISTINCT
Style_id,
'99999' AS WebCategoryID
FROM ItemCategory WHERE Style_id NOT IN (
SELECT Style_id FROM ItemWebCategory
);
The NOT IN excludes any Style_id values that already exist in ItemWebCategory.
You have two straight-forward options:
NOT EXISTS
insert into ItemWebCategory (Style_id,WebCategoryID)
select distinct Style_id,WebCategoryID = '99999'
from ItemCategory ic
where style_id in ('1109068','168175', '68435', '545457', '69189')
AND NOT EXISTS (SELECT 1
FROM ItemWebCategory iwc
WHERE ic.Style_id = iwc.Style_id
);
EXCEPT
insert into ItemWebCategory (Style_id,WebCategoryID)
select Style_id,WebCategoryID = '99999'
from ItemCategory
where style_id in ('1109068','168175', '68435', '545457', '69189')
EXCEPT
SELECT Style_id
FROM ItemWebCategory;
Now there's no need for DISTINCT because EXCEPT implies DISTINCT
One more useful option is a MERGE. This has performance benefits due to Halloween Protection (an entire subject in itself) as explained by Paul White:
MERGE ItemWebCategory AS target
USING (
select Style_id, WebCategoryID = '99999'
from ItemCategory
where style_id in ('1109068','168175', '68435', '545457', '69189')
) AS source
ON target.Style_id = source.Style_id
WHEN NOT MATCHED THEN INSERT
(Style_id, WebCategoryID)
VALUES (source.Style_id, source.WebCategoryID);

merge statement when not matched by source then insert to another table

I have created two tables customersrc and customertemp with the columns:
customertemp
ID name age addr cityid isactive
34 Gi 24 Chennai 1 1
customersrc
CustomerId CustomerName CustomerAge CustomerAddress
1 Gi 24 madurai
2 Pa 23 Tirupur
3 MI 27 Tirupur
Now I need to insert pa and mi data value to the temp table bcz it is not matched with the rows of customertemp. And the row gi data will be updated which was matched.
I used the following MERGE statement
DECLARE #cityid INT SET #cityid=1
MERGE Temp.dbo.customersrc as src_customer
USING ( SELECT CustomerName,CustomerAge,CustomerAddress FROM customertemp) as temp_customer
ON src_customer.name=temp_customer.CustomerName
AND
src_customer.cityid=#cityid
WHEN MATCHED THEN
UPDATE SET
src_customer.age=temp_customer.CustomerAge,
src_customer.addr=temp_customer.CustomerAddress,
src_customer.isactive=1
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET src_customer.isactive=0 ; -- here i need the insert statement to insert in another table
Questions:
is it possible to write insert statement inside the when not matched by source query?
if it is not possible then how to achieve this using merge?
in a simple set theory I need to put the customersrc(table_B)-customertemp (table_A). B-A value into the another or temp table.
One of the main usages of the MERGE statement is to perform so called "UPSERTS" (Update matching records, insert new records), so it is definitely possible to do what you want. Just add the following to the last part of your MERGE statement:
WHEN NOT MATCHED BY TARGET THEN
INSERT (name, age, addr, cityid, isactive)
VALUES (CustomerName, CustomerAge, CustomerAddress, #cityid, 1)
If you also need to insert data into a 3rd table, depending on whether rows are updated or inserted, you can use the OUTPUT clause of the merge statement. Check out the documentation: http://technet.microsoft.com/en-us/library/ms177564.aspx
Me: Why do you want to insert to another table?
You: To show the user who are not in the customertemp table.
So your requirement is not to insert into another table. Your requirement is to get the missing users.
You could do that with a dummy UPDATE (SET SomeCol = SomeCol) and OUTPUT. But that is a hack that I would try to avoid.
It is probably easier to do this in two statements. Here's how you'd get the missing rows:
SELECT temp_customer.*
FROM (SELECT CustomerName,CustomerAge,CustomerAddress FROM customertemp) as temp_customer
LEFT JOIN customersrc ON src_customer.name=temp_customer.CustomerName AND src_customer.cityid=#cityid
WHERE customersrc.cityid IS NULL

Oracle SQL: merge with more conditions than matched/not matched

I'm needing some help with a MERGE command in Oracle. Basically I have this command but I want to optimize it a little more:
MERGE INTO swap USING dual ON (SELECT id FROM student WHERE number = '123')
WHEN MATCHED THEN
UPDATE SET swapped = 1, last_swap = sysdate
WHEN NOT MATCHED THEN
INSERT (student_id, swapped, last_swap) VALUES ((SELECT id FROM student WHERE number= '123'), 1, sysdate)
Right now this will insert or update a register on SWAP table. However, I would like to protect it from inserting NULL on the student_id if there's no student with that number on STUDENT table (I don't want to simply not allow NULL values on sudent_id of SWAP table).
Other thing, I'm repeating SELECT id FROM student WHERE number = '123' two times, how can I change this to execute it only once (store the result in an alias or something)?
Thanks a lot in advance!
Your merge statement should use the "Select from student" as the table you are merging from.
Can you post some sample data as well?
The below query is assuming that ID is the column on which you are merging and it cannot be null.
MERGE INTO swap
USING (SELECT id FROM student WHERE number = '123' and id is not null) stu
on (stu.id = swap.id)
WHEN MATCHED THEN
UPDATE SET swapped = 1, last_swap = sysdate
WHEN NOT MATCHED THEN
INSERT (student_id, swapped, last_swap) VALUES (stu.id , 1, sysdate);