Place an Insert Statement into a Select Statement - mysql

I have read the other questions and all of the posted comments/answers to questions that are similar to this one. None of them seem to answer this question directly.
I am wanting to know if there is a way to either concatenate or place an INSERT, DELETE or UPDATE statement into a SELECT statement.
If so how? Could this be done by using a derived table function or a subSelect statement?
And example would be:
INSERT INTO Customer (name)
VALUES 'Test Name'
but place this into a SELECT statement
Example pseudo code:
SELECT *
FROM Customer
WHERE
Customer.name = (INSERT INTO Customer (name) VALUES 'Test Name')
The big thing here is getting the INSERT statement into the SELECT statement in an unconventional way.
Thank you and hopefully this will strike up some good conversation/ideas/results!
Reason for wanting to know this:
Our current DBMS (Fishbowl) does not allow us to use an UPDATE, DELETE or INSERT statement with is SQL compiler and we are wanting to mass alter our fields/clean up our tables.
To know if it is possible

You may have a select within an insert but not the other way
around.
A select within an insert statement could be used to copy values from a table to another. (You are just writing into a table after a read from another)
But an insert within a select doesn't make sense! What are you going to insert when you are running a select from a table(or just reading data)?(how is it possible to write when you are only allowed to read?)
Your situation, if you don't have access to run an insert then it doesn't matter where you put the statement, you just can't because you aren't allowed to!
But if you are talking about your query engine/database wrapper not allowing a direct insert, then its probably because it requires an application/program to insert data into to rather than just a query(as your engine doesn't already have the capability to perform that operation).

Related

Combine INSERT and SELECT in one SQL query (Zapier)

I'm crafting Zapier task to insert entry in MySQL if there is no entry with specified unique key or do nothing.
I need to try to insert new row into some table, but if email of new entry is already INSERT will silently throw warning (due to IGNORE keyword).
INSERT IGNORE users(email, hashed_password)
VALUES ('<email>`, '<some_hashed_password>')
But in both scenarios my query is not returning anything and Zapier ends task with this message:
Question: Is there some way to have one complex SQL command that will combine INSERT and SELECT so with one query I will get some result set from from DB, not empty object or whatever INSERT returns?
P.S. This works in MySQL:
INSERT IGNORE reporting.users(`email`, `password`)
VALUES ("test#test.ts", "test");
SELECT * FROM reporting.users as u WHERE u.email = "test#test.ts";
but this consists of two queries and this doesn't work in Zapier.
This is an old question but I was grappling with the same issue today. In trying to find a solution I came across this qn and so when I found a solution / work-around I thought I'd do the decent thing and post back...
Based on the red "Bargle" error in their post I believe zmii must have been trying to use the MySQL custom search query. Zapier has to have an output from the query or it faults. I did some looking around and crafted my custom query thus:
SELECT IFNULL( (SELECT employee_id FROM timesheets.employees WHERE employee_id = <Step 6 | sheet_data_id> LIMIT 1) ,0) AS result;
based on the selected answer here.
So, my query will output an employee ID if it is found and 0 if not. I then inserted a Zapier PATHS step which I based on the output 'result' from my custom query. If the result is greater than 0 I update an existing record. If it is 0 then I insert a new record. I suspect I could use the custom query code to do the branching and updating/inserting but I didn't try that yet as I have other things to try first.
Edit
Actually I have had to revise this answer based on my conversation with Zapier here. I've retained the original answer but hidden it. The syntax works but only if the query is a SELECT query, it will not work for an INSERT or UPDATE query. See the discussion in the comments of the linked question for details. Essentially it is not possible to do an insert or update operation via the Zapier MySQL Custom Query step at this stage.

What is proper way to set and compare variable inside an sql trigger

Am populating a table using a trigger after an insert event occurs on another table and that worked fine. However i then noticed that the trigger would still insert a new row for existing records. To fix this, I want to create the trigger again but this time it would only fire if a condition is met...but not having previously used triggers in the past am getting a syntax error and not able to identify what am doing wrong. Kindly have a look and help me fix this
CREATE TRIGGER `students_gen_insert`
AFTER INSERT ON `students` FOR EACH ROW
BEGIN
INSERT INTO records (student_id, subject_id)
SELECT new.student_id, subjects.subject_id
FROM subjects
WHERE category = new.class;
END;
Am currently using MySql 5.6.17 version.
It is generally not a good idea to SELECT from the table the trigger is on, and forbidden to UPDATE or INSERT (not that you are doing those). Assuming you are trying to get the values for the row just inserted, the first SET ... SELECT you have is needless; just use NEW.fieldname to get the fields of the inserted row.
The second SET ... SELECT and following condition are a bit confusing. If referential integrity is being maintained, I would think it would be impossible for the records table to refer to that particular student_id of the students table at the point the trigger is executed. Perhaps this was to avoid the duplicate inserts from the trigger's previous code? If so, it might help for you to post that so we can pinpoint the actual source of redundant inserts.

INSERT INTO statement in MySQL

I'm trying to work with YEAR function on one column in the DB and then add the results to a different table in the DWH.
What am I doing wrong?
INSERT INTO example_dwh1.dim_time (date_year)
SELECT YEAR(time_taken)
FROM exampledb.photos;
When removing the INSERT INTO line, I get the results I want, but I'm not able to insert them into the dwh table.
Thanks for your help!
The following select works, but I don't see the data in the table after the insert:
INSERT INTO example_dwh1.dim_time (date_year)
SELECT YEAR(time_taken)
FROM exampledb.photos;
There is rather broad. Assuming you have no errors in the insert, you might have:
You are incorrectly querying dim_time, so the data is there but your check is wrong.
You are inserting into dim_time in one database but querying it in another.
Assuming you have errors but are missing them, here are some possibilities:
The database does not exist.
The table does not exist.
The column is misnamed.
Other columns are declared NOT NULL.
Triggers defined on the table are preventing the insert.
Unique constraints/indexes on the table are preventing the insert.
Your question does not provide enough information to be more specific. However, it seems highly suspicious to be inserting a bunch of years -- which might include many duplicates -- into a dimension table.

How to efficiently use first_or_initialize when records usually already exist

I'm trying to figure out how to use ActiveRecord to execute the following psuedocode:
rows_updated = UPDATE my_table SET my_column="abc" WHERE id=123
if rows_updated == 0 then INSERT INTO my_table (id, my_column) VALUES (123, "abc")
The reason for this is most of the time the record already exists. I want to save myself the extra SELECT query that first_or_create! seems to generate.
Any ideas?
There is also different and more elegant solution (from my point of view) for this case
One of the options is using a replace command instead of all this code.
just run:
REPLACE INTO my_table (id, my_column) VALUES (123, "abc")
this solution works just fine in most cases, but if you have a very high load on this pice of code, you should consider using
INSERT .... ON DUPLICATE KEY UPDATE
First do a find or initialize so that if the id is not there it will create the object. then check if it is new. If new save it else update it.
obj= find_or_initialize_by_id(obj)
obj.new_record? ? prod.save! : *update the entry*
I'm all for high-efficiency database solutions and all, but that first query ought to be taking something like 1 or 2 ms, and if it's looking like it's mysteriously less efficient than the update it would partly be because the database may require a physical read to access it -- the update then benefits from that pre-caching.
So unless this operation is a measurably significant performance problem I'd not try to optimise it out.

MySQL - Split up INSERT in to 2 queries maybe

I have an INSERT query which looks like:
$db->Query("INSERT INTO `surfed` (user, site) VALUES('".$data['id']."', '".$id."')");
Basically I want to insert just like the above query but if the site is already submitted by another user I don't want it to then re-submit the same $id in to the site column. But multiple users can view the same site and all users need to be in the same row as the site that they have viewed which causes the surfed table to have 10s of thousands of inserts which dramatically slows down the site.
Is there any way to maybe split up the insert in some way so that if a site is already submitted it won't then submit it again for another user. Maybe there's a way to use UPDATE so that there isn't an overload of inserts?
Thanks,
I guess the easiest way to do it would be setting up a stored procedure which executes a SELECT to check if the user-site-combination is already in the table. If not, you execute the insert statement. If that combination already exist, you're done and don't execute the insert.
Check out the manual on stored procedures
http://dev.mysql.com/doc/refman/5.1/en/create-procedure.html
You need to set a conditional statement that asks whether the id already exists then if it does update otherwise insert
If you don't need to know whether you actually inserted a line, you can use INSERT IGNORE ....
$db->Query("INSERT IGNORE INTO `surfed` (user, site) VALUES('".$data['id']."', '".$id."')");
But this assumes that you have a unique key defined for the columns.
IGNORE here will ignore the Integrity constraint violation error triggered by attempting to add the same unique key twice.
The MySQL Reference Manual on the INSERT syntax has some informations on that http://dev.mysql.com/doc/refman/5.5/en/insert.html