Include all of these commands in one big MySQL statement? - mysql

For an assignment, I have to include all of these keywords in one big MySQL statement: select, from, where, group by, order by, inner join, insert, update, delete.
Obviously all but the last 3 are easy to include in 1 statement.
However, I'm having a problem with using union on 2 SQL statements (one with select, etc. and the other with insert).
For example, I have:
SELECT * FROM Database
INNER JOIN (O_Database INNER JOIN ...)
ON ...
GROUP BY ...
ORDER BY ...
UNION
INSERT INTO Database (...) VALUES (...)
But I run into errors with using UNION this way. Is there a simple statement that includes all of these keywords?

I see no solution to put DELETE in there. You can build a select statement with all the stuff required and use this in an INSERT ON DUPLICATE KEY UPDATE Statement. But DELETE? No. In Oracle this would be possible by using the MERGE statement, but this is not available in MySQL. So I guess, there is no solution to the task given.
INSERT INTO ...
SELECT ... -- using from, where, group by, order by, and inner join here
ON DUPLICATE KEY
UPDATE ...

Well, you can do something like
INSERT INTO A
SELECT whatever FROM B;
or
UPDATE A
INNER JOIN (SELECT * FROM B ) C ON A.id = C.id
SET A.whatever = C.whatever;
or
DELETE
FROM A WHERE A.whatever IN (SELECT whatever FROM B);
But you can not combine DELETE and UPDATE or UPDATE and INSERT. Just one of the operations with a SELECT.

Related

MySQL internal order of operations in SELECT query

What is the internal order of operations in a MySQL SELECT query and a relational query?
For instance, a SELECT query to a single table:
SELECT `name`
FROM `users`
WHERE `publication_count`>0
ORDER BY `publication_count` DESC
I know that at first all table fields are fetched and then only name field is left at the end. Does it happen before or after the condition in WHERE is applied? When is ORDER BY applied?
A relational query using two tables:
SELECT `users`.`name`, `post`.`text`
FROM `users`, `posts`
WHERE `posts`.`author_id`=`user`.`id`
ORDER BY `posts`.`date` DESC
Same question. What happens after what? (I know that at first the Cartesian product is generated)
Processing regarding your example simplifying the rules goes as follow:
1. FROM -- all elements in list (including multiple tables)
2. WHERE -- discard rows not matching conditions
3. SELECT -- output rows are computed (not fetched)
4. ORDER BY -- sort output rows
Also, you shouldn't be using old-fashioned implicit join syntax in WHERE condition. Instead, please use JOIN:
SELECT ...
FROM users
INNER JOIN posts ON users.id = posts.author_id
ORDER BY ...

Nested SELECT SQL Queries Workbench

Hi i have this query but its giving me an error of Operand should contain 1 column(s) not sure why?
Select *,
(Select *
FROM InstrumentModel
WHERE InstrumentModel.InstrumentModelID=Instrument.InstrumentModelID)
FROM Instrument
according to your query you wanted to get data from instrument and instrumentModel table and in your case its expecting "from table name " after your select * .when the subselect query runs to get its result its not finding table instrument.InstrumentModelId inorder to fetch result from both the table by matching you can use join .or you can also select perticuler fields by tableName.fieldName and in where condition use your condition.
like :
select Instrument.x,InstrumentModel.y
from instrument,instrumentModel
where instrument.x=instrumentModel.y
You can use a join to select from 2 connected tables
select *
from Instrument i
join InstrumentModel m on m.InstrumentModelID = i.InstrumentModelID
When you use subqueries in the column list, they need to return exactly one value. You can read more in the documentation
as a user commented in the documentation, using subqueries like this can ruin your performance:
when the same subquery is used several times, mysql does not use this fact to optimize the query, so be careful not to run into performance problems.
example:
SELECT
col0,
(SELECT col1 FROM table1 WHERE table1.id = table0.id),
(SELECT col2 FROM table1 WHERE table1.id = table0.id)
FROM
table0
WHERE ...
the join of table0 with table1 is executed once for EACH subquery, leading to very bad performance for this kind of query.
Therefore you should rather join the tables, as described by the other answer.

Delete query to delete entries without constraints

I have a table say table1 with 50 records, table1's records are tied up with other child tables using constraints.
Not all the 50 records have constraints, there could be few records (say 15 ) without constraints, so i want to run a delete query deleting 15 entries alone out of total 50.
I tried delete ignore statement:
delete ignore from table1;
but it didn't help & I got this error:
Cannot delete or update a parent row:
a foreign key constraint fails
What is the best possible way to accomplish this in mysql queries?
DELETE FROM table1 WHERE NOT EXISTS (SELECT * FROM details_table d WHERE d.table1_id = table1.id)
Here's a simple, readable, efficient query that will do it for you:
DELETE FROM table1
WHERE id NOT IN (
SELECT table1_id FROM details_table_1
UNION
SELECT table1_id FROM details_table_2
-- more unions to other child tables as required
);
I've always preferred joins to sub-queries that use IN():
http://dev.mysql.com/doc/refman/5.5/en/rewriting-subqueries.html
Sometimes there are other ways to test
membership in a set of values than by
using a subquery. Also, on some
occasions, it is not only possible to
rewrite a query without a subquery,
but it can be more efficient to make
use of some of these techniques rather
than to use subqueries. One of these
is the IN() construct.
...
A LEFT [OUTER] JOIN can be faster than
an equivalent subquery because the
server might be able to optimize it
better—a fact that is not specific to
MySQL Server alone. Prior to SQL-92,
outer joins did not exist, so
subqueries were the only way to do
certain things. Today, MySQL Server
and many other modern database systems
offer a wide range of outer join
types.
Here's how to answer your question with LEFT OUTER JOIN:
DELETE FROM table1
LEFT OUTER JOIN child_table_1 c1 ON table1.id = c1.table_1_id
LEFT OUTER JOIN child_table_2 c2 ON table1.id = c2.table_1_id
-- More joins for additional child tables here
WHERE c1.table_1_id IS NULL
AND c2.table_1_id IS NULL
-- AND other child tables
;

Loops in MySQL alone

I'd like to select from one table and use the results of that select to update another table, but only based on certain conditions. Is this possible with a 1-time SQL query?
Yes it is.
UPDATE
tableToUpdate AS ttu
[LEFT|RIGHT|INNER] JOIN
otherTable AS ot
ON
joinCondition
SET
ttu.field = ot.field
WHERE
conditionsToBeMet
AS otherTable you can just use the SELECT query that you use to fetch your resultset.

MYSQL: subquery into a table updated in the main query

I'd like do something like this:
In table TAGS find a row with name='someName', and remeber it's id
In the same table find another row with someCondition and set in this row col refference=the id from above
Tried to do this using a subquery, but mysql refused saying I can't subquery a table that I'm updating in the main query.
How can I otherwise implement the above idea?
Thank you
Convert your subquery to a join and then UPDATE:
You can also perform UPDATE operations covering multiple tables. However, you cannot use ORDER BY or LIMIT with a multiple-table UPDATE. The table_references clause lists the tables involved in the join. Its syntax is described in Section 12.2.8.1, “JOIN Syntax”. Here is an example:
UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;
The preceding example shows an inner join that uses the comma operator, but multiple-table
UPDATE statements can use any type of join permitted in SELECT statements, such as LEFT JOIN.
you can do this
update TAGS set
reference =
(select my_id from
(select id as my_id from TAGS where name='someName')
as SUB_TAGS)
where someCondition;
Not advisable though.
Edit#1 You can avoid the sub-queries altogether -- as taspeotis rightly mentioned, by joining the same table with the criteria. Here goes the code for that:
UPDATE
TAGS t1, TAGS t2
SET
t1.reference = t2.id
WHERE
t2.name = 'someName'
AND
t1.someField = someCondition;
This is a better approach.