MySQL INSERT with multiple nested SELECTs - sql

Is a query like this possible? MySQL gives me an Syntax error. Multiple insert-values with nested selects...
INSERT INTO pv_indices_fields (index_id, veld_id)
VALUES
('1', SELECT id FROM pv_fields WHERE col1='76' AND col2='val1'),
('1', SELECT id FROM pv_fields WHERE col1='76' AND col2='val2')

I've just tested the following (which works):
insert into test (id1, id2) values (1, (select max(id) from test2)), (2, (select max(id) from test2));
I imagine the problem is that you haven't got ()s around your selects as this query would not work without it.

When you have a subquery like that, it has to return one column and one row only. If your subqueries do return one row only, then you need parenthesis around them, as #Thor84no noticed.
If they return (or could return) more than row, try this instead:
INSERT INTO pv_indices_fields (index_id, veld_id)
SELECT '1', id
FROM pv_fields
WHERE col1='76'
AND col2 IN ('val1', 'val2')
or if your conditions are very different:
INSERT INTO pv_indices_fields (index_id, veld_id)
( SELECT '1', id FROM pv_fields WHERE col1='76' AND col2='val1' )
UNION ALL
( SELECT '1', id FROM pv_fields WHERE col1='76' AND col2='val2' )

Related

sql insert multiple rows from another table

I have tables:
ContainerSubTypes (Id, Name) with many records,
WorkAreas (Id, Name) with only one row,
WorkAreaContainerSubTypes table (Id, WorkAreaId, ContainerSubTypeId) - empty table.
I need to insert data into WorkAreaContainerSubTypes table, it should look like:
(1, 1, containersubtype1_id)
(2, 1, containersubtype2_id)
(3, 1, containersubtype3_id)
And I'm trying sql like:
INSERT INTO WorkAreaContainerSubTypes (WorkAreaId, ContainerSubTypeId)
VALUES
(1, (SELECT Id FROM ContainerSubTypes));
But SELECT query has more than 1 row and it throws error.
How can I implement that inserting?
VALUES table value constructor specifies a set of row value expressions to be constructed into a table, so you need a different statement:
INSERT INTO WorkAreaContainerSubTypes (WorkAreaId, ContainerSubTypeId)
SELECT 1, Id
FROM ContainerSubTypes;
As an additional note, you may use VALUES only if SELECT Id FROM ContainerSubTypes statement returns a single row or no rows (perhaps with an optional WHERE clause):
INSERT INTO WorkAreaContainerSubTypes (WorkAreaId, ContainerSubTypeId)
VALUES
(1, (SELECT Id FROM ContainerSubTypes WHERE Name = 'Some name'));
Just use insert . . . select:
INSERT INTO WorkAreaContainerSubTypes (WorkAreaId, ContainerSubTypeId)
SELECT 1, Id
FROM ContainerSubTypes;

Can INSERT with ON CONFLICT in PostgreSQL be conditional in SQL

I have the following SQL query:
WITH inserted_id AS (
INSERT INTO users (email,name,user_id,user_name,source)
VALUES (
'a',
'b',
'c',
'd',
'e')
ON CONFLICT (email) DO UPDATE SET
user_id='c',
user_name='d',
source='e'
RETURNING id AS users_id
)
INSERT INTO users_groups (users_id, groups_id)
SELECT users_id, 5 FROM inserted_id;
I would like the second INSERT to users_groups to be conditional on the first INSERT being done without any conflicts — that is, the ON CONFLICT part is not run. Can this be done with the query or what do I need to change?
You are doing something in the on conflict, so the row will be returned.
I think you can do:
INSERT INTO users_groups (users_id, groups_id)
SELECT users_id, 5
FROM inserted_id
WHERE users_id <> 'aa';
If you can, you can simply use on conflict do nothing. Then the id will not be returned.

Insert data in multiple tables at a time with repeated values

I have to insert data into first and second table directly. But the third table which I received data as array and inserted into 3rd table as same.
In my 3rd table values will be repeated. Ex:
values:
{name=ff,age=45,empid=23,desig=se,offid=1,details=kk,offid=2,details=aa,offid=3,details=bb,offid=4,details=cc}
So using 2nd table userid as same for all the offid, but details and other columns are different
#My issue is i will get single hit but i need to iterate for 3rd table.
with first_insert as (
insert into sample(name,age)
values(?,?)
RETURNING id
),
second_insert as (
insert into sample1(empid,desig)
values((select id from first_insert),?)
RETURNING userid
)
insert into sample2(offid,details)
values((select userid from second_insert),?)
Is this available or possible in PostgreSQL?
Yes, absolutely possible.
You can join rows from CTEs to VALUES expressions to combine them for a new INSERT in a data-modifying CTE. Something like this:
WITH first_insert AS (
INSERT INTO sample(name,age)
VALUES (?,?)
RETURNING id
)
, second_insert AS (
INSERT INTO sample1(empid, desig, colx)
SELECT i1.id, v.desig, v.colx
FROM first_insert i1
, (VALUES(?,?)) AS v(desig, colx)
RETURNING userid
)
INSERT INTO sample2(offid, details, col2, ...)
SELECT i2.userid, v.details, ...
FROM second_insert i2
, (VALUES (?,?, ...)) AS v(details, col2, ...);

SQL: How to insert data into a table with column names

When inserting data into a SQL Server table, is it possible to specify which column you want to insert data to?
For a table with
I know you can have syntax like this:
INSERT INTO MyTable (Name, col4_on, col8_on, col9_on)
VALUES ('myName', 0, 1, 0)
But the above syntax becomes unwieldy when you have lots of columns, especially if they have binary data. It becomes hard to match up which 1 and 0 go with which column. I'm hoping there's a named-parameter like syntax (similar to what C# has) which looks like the following:
INSERT INTO MyTable
VALUES (Name: 'myName', col4_on: 0, col8_on: 1, col9_on: 0)
Thanks
You must specify the column names. However, there is one exception. If you INSERTing exactly the same number of columns as the target table has in the same order as they are in the table, use this syntax:
INSERT INTO MyTable
VALUES ('val1A', 'val4A', 'val8A')
Note that this is a fragile way of performing an INSERT, because if that table changes, or if the columns are ordered differently on a different system, the INSERT may fail, or worse-- it may put the wrong data in each column.
I've found that when I INSERT a lot of columns, I find the queries easier to read if I can group them somehow. If column names are long, I may put them on separate lines like so:
INSERT INTO MyTable
(
MyTable_VeryLongName_Col1,
MyTable_VeryLongName_Col4,
MyTable_VeryLongName_Col8,
-- etc.
)
SELECT
Very_Long_Value_1,
Very_Long_Value_4,
Very_Long_Value_8,
-- etc.
Or you can group 2 columns on a line, or put spaces on every 5, or comment every 10th line, etc. Whatever makes it easier to read.
If you find including column names onerous when INSERTing a lot of rows, then try chaining the data together:
INSERT INTO MyTable (col1, col4, col8)
VALUES ('val1A', 'val4A', 'val8A'),
('val1B', 'val4B', 'val8B'),
-- etc.
Or UNION them together:
INSERT INTO MyTable (col1, col4, col8)
SELECT 'val1A', 'val4A', 'val8A'
UNION ALL 'val1B', 'val4B', 'val8B'
UNION ALL ... -- etc.
Or, SELECT them from another table:
INSERT INTO MyTable (col1, col4, col8)
SELECT val1, va4, val8
FROM MyOtherTable
WHERE -- some condition is met
INSERT INTO MyTable (col1, col4, col8)
VALUES ('val1', 'val4', 'val8')
This statement will add values to the columns mentioned in your INSERT INTO statement, you can write the above query in the following formats it will not make any difference .
INSERT INTO MyTable (col8, col1, col4)
VALUES ('val8', 'val1', 'val4')
OR
INSERT INTO MyTable (col4, col8, col1)
VALUES ('val4', 'val8', 'val1')
to Add multiple rows at a time you can pass multiple rows at a time in you values clause something like this
INSERT INTO MyTable (col4, col8, col1)
VALUES ('val4', 'val8', 'val1'),
('val4', 'val8', 'val1'),
('val4', 'val8', 'val1'),
('val4', 'val8', 'val1')
The order of the values should match the order of the columns
mentioned in your INSERT INTO statement.
All above statement will have the same result.
keeping one thing in mind once you have mentioned a column you must provide a value for it
like this
INSERT INTO MyTable (col1, col4, col8)
VALUES ('val1', null, 'val8')
but you cannot do something like this
INSERT INTO MyTable (col1, col4, col8)
VALUES ('val1', 'val8')
I figured out a way around this but it's rather hacky and only works for tables which has columns with unique values:
INSERT INTO MyTable (Name)
VALUES ('myName')
UPDATE MyTable
SET col4_on=0, col8_on=1, col9_on=0
WHERE Name = 'myName'
This could be expanded into a multiple row insert as follows:
INSERT INTO MyTable (Name)
VALUES ('row1'), ('row2'), ('row3')
UPDATE MyTable SET col4_on=0, col8_on=1, col9_on=0 WHERE Name = 'row1'
UPDATE MyTable SET col4_on=1, col8_on=0, col9_on=0 WHERE Name = 'row2'
UPDATE MyTable SET col4_on=1, col8_on=1, col9_on=1 WHERE Name = 'row3'
No, there is no way to do specifically what you want. The closest thing you can do is to use the column creation order to avoid use the columns names on the insert command. As this:
If you have a table like
tableA ( id, name, phone )
You can insert values on it using
insert into tableA values ( 1, 'Name', '555-9999' );
But be carefull, you have to follow the exact order on the fields of your table, otherwise you can have an error and worst, put wrong data in wrong fields.
Nope you cannot do it, the only other alternative for you would be insert from select
insert into MyTable
select 'val1' as col1, 'val4' as col4, 'val8' as col8 --if any extra columns then just do "null as col10"
assuming the order is same in table

sql query multiple record insertion

how can i insert multiple records using single sql statement
For SQL Server 2005 you could do the following:
INSERT INTO your_table (id, field_1, field_2)
SELECT 1, 'some-data-a', 'some-data-1'
UNION ALL
SELECT 2, 'some-data-b', 'some-data-2'
UNION ALL
SELECT 3, 'some-data-c', 'some-data-3'
UNION ALL
SELECT 4, 'some-data-d', 'some-data-4';
In most modern DBMSes, including SQL Server 2008 and MySQL 5, you could use a much neater syntax:
INSERT INTO your_table (id, field_1, field_2) VALUES
(1, 'some-data-a', 'some-data-1'),
(2, 'some-data-b', 'some-data-2'),
(3, 'some-data-c', 'some-data-3'),
(4, 'some-data-d', 'some-data-4');
Using MySQL:
INSERT INTO TABLE (col1, col2) VALUES
(val1a, val1b),
(val2a, val2b),
(valNa, valNb);
You should use table types and use bulk insert.
EDIT:
http://msdn.microsoft.com/en-us/library/bb510489.aspx
This can explain further on using either one. This works for SQL server, I am not so sure about other databases. Both are very useful for a lot of records to be inserted at one go.
You can insert multiple records from a subquery as well.
INSERT INTO TABLE (col1, col2) (select a,b from SUB)