Insert into select and update in single query - sql

I have 4 tables: tempTBL, linksTBL and categoryTBL, extra
on my tempTBL I have: ID, name, url, cat, isinserted columns
on my linksTBL I have: ID, name, alias columns
on my categoryTBL I have: cl_id, link_id,cat_id
on my extraTBL I have: id, link_id, value
How do I do a single query to select from tempTBL all items where isinsrted = 0 then insert them to linksTBL and for each record inserted, pickup ID (which is primary) and then insert that ID to categoryTBL with cat_id = 88. after that insert extraTBL ID for link_id and url for value.
I know this is so confusing, put I'll post this anyhow...
This is what I have so far:
INSERT IGNORE INTO linksTBL (link_id,link_name,alias)
VALUES(NULL,'tex2','hello'); # generate ID by inserting NULL
INSERT INTO categoryTBL (link_id,cat_id)
VALUES(LAST_INSERT_ID(),'88'); # use ID in second table
I would like to add here somewhere that it only selects items where isinserted = 0 and iserts those records, and onse inserted, will change isinserted to 1, so when next time it runs, it will not add them again.

As longneck said, you cannot do multiple things in one query, but you can in a stored procedure.

http://dev.mysql.com/doc/refman/5.1/en/insert-select.html
INSERT INTO linksTBL (link_id,link_name,alias)
SELECT field1, field2, field3
FROM othertable
WHERE inserted=0;

this is not possible to do in a single query. you will have to insert the rows, then run a separate update statement.

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

Inserting data into a table(mutliple columns) which has primary key from another data which has data except primary key

I have a table that has 3 columns ID(Primary Key), Name, City.
I need to import data from another table that has only Name and City.
I can write insert into table 1(Name, City) select Name, City from table2.
But then I need ID in table 1 which needs to be inserted using a sequence.
I tried this:
insert into table1(ID, Name,City) values(seq.nextval, select distinct name, city from table2). But I am receiving an error saying an insufficient number of values.
I am trying it in SQL Oracle. Can someone please help me with this?
You are mixing the insert ... values and insert ... select syntax.
You edited your question to include distinct, implying you have duplicate name/city pairs that you want to suppress; but neither version gets the error you reported. If you don't have duplicates then you can just do:
insert into table1(ID, Name,City)
select seq.nextval, name, city from table2;
If you do have duplicates then you can't just add the distinct keyword, but you can use a subquery:
insert into table1 (id, name, city)
select seq.nextval, name, city
from (
select distinct name, city
from table2
);
db<>fiddle
You could also set the ID via a trigger. If you we're on a recent version you could use an identity column instead - but you tagged the question with Oracle 11g, where those are not available.

Will order by preserve?

create table source_table (id number);
insert into source_table values(3);
insert into source_table values(1);
insert into source_table values(2);
create table target_table (id number, seq_val number);
create sequence example_sequence;
insert into target_table
select id, example_sequence.nextval
from
> (select id from source_table ***order by id***);
Is it officially assured that for the id's with the lower values in source_table corresponding sequence's value will also be lower when inserting into the source_table? In other words, is it guaranteed that the sorting provided by order by clause will be preserved when inserting?
EDIT
The question is not: 'Are rows ordered in a table as such?' but rather 'Can we rely on the order by clause used in the subquery when inserting?'.
To even more closely illustrate this, the contents of the target table in the above example, after running the query like select * from target_table order by id would be:
ID | SEQ_VAL
1 1
2 2
3 3
Moreover, if i specified descending ordering when inserting like this:
insert into target_table
select id, example_sequence.nextval
from
> (select id from source_table ***order by id DESC***);
The output of the same query from above would be:
ID | SEQ_VAL
1 3
2 2
3 1
Of that I'm sure, I have tested it multiple times. My question is 'Can I always rely on this ordering?'
Tables in a relational database are not ordered, and any apparent ordering in the result set of a cursor which lacks an ORDER BY is an artifact of data storage, is not guaranteed, and later actions on the table may cause this apparent ordering to change. If you want the results of a cursor to be ordered in a particular manner you MUST use an ORDER BY.

Insert some variable columns with constants

What I'm looking to do with my code is insert some variable number of rows into test_table where 'policy' in source_table matches 'bond_ser' in policy_custsgt and 'SNL_ID' in source_table matches 'inst_key' in raw_table.
I want it to insert serial_number and ID along with some other constants. I can get it to insert serial_number and ID just fine, but how do I get it to add some constants in other fields of the table every time it inserts the variables from the other tables?
This is the code I currently have, if I remove the "'122812', '999999', 'myname'" from the first line it works fine but will only populate the serial_number and ID columns of my table with each insert.
INSERT INTO test_table(serial_number, ID, '122812', '999999', 'myname')
SELECT policy, SNL_ID
FROM source_table
WHERE (policy IN (SELECT bond_ser from policy_custsgt)) AND
(SNL_ID in (select inst_key from raw_table))
Thanks!
Of course, I over looked the simple solution. All I needed to do was move those constants I wanted down from the INSERT statement to the SELECT statment, and add the column names in the INSERT so:
INSERT INTO test_table(serial_number, ID, starting_date, ending_date, user_id)
SELECT policy, SNL_ID, '122812', '999999', 'myname'
FROM source_table
WHERE (policy IN (SELECT bond_ser from policy_custsgt)) AND
(SNL_ID in (select inst_key from raw_table))

SQL to search duplicates

I have a table for animals like
Lion
Tiger
Elephant
Jaguar
List item
Cheetah
Puma
Rhino
I want to insert new animals in this table and I am t reading the animal names from a CSV file.
Suppose I got following names in the file
Lion,Tiger,Jaguar
as these animals are already in "Animals" table, What should be a single SQL query that will determine if the animals are already exist in the table.
Revision 1
I want a query that will give me the list of animals that are already in table. I donot want a query to insert that animal.
I just want duplicate animals
To just check if a Lion is already in the table:
select count(*) from animals where name = 'Lion'
You can do the check and the insert in one query with a where clause:
insert into animals (name)
select 'Lion'
where not exists
(
select * from animals where name = 'Lion'
)
In reply to your comment, to select a sub-list of animals:
select name from animals where name in ('Lion', 'Tiger', 'Jaguar')
This would return up to 3 rows for each animal that already exists.
SELECT COUNT(your_animal_column) FROM tblAnimals WHERE your_animal_column = ?;
The question marks get filled by your csv values.
If this statement returns more than 0 there the value already exists
If your incoming file is already in a normalized column format, instead of comma separated like you have displayed, it should be easy. Create a temp table for the insert, then something like..
insert into YourLiveTable ( animalname )
select Tmp.animalname
from YourTempInsertTable Tmp
where Tmp.animalname not in
( select Live.animalname
from YourLiveTable Live )
To match your revised request... just use the select portion and change "NOT IN" to "IN"
select Tmp.animalname
from YourTempInsertTable Tmp
where Tmp.animalname IN
( select Live.animalname
from YourLiveTable Live )
How about
SELECT ANIMAL_NAME, COUNT(*)
FROM ANIMALS
GROUP BY ANIMAL_NAME
HAVING COUNT(*) > 1
This should give you all the duplicate entries