explain the USING command - mysql

Take a look...
http://search.mysql.com/search?site=refman-41&q=using&lr=lang_en
The official MySQL site doesn't explain the USING command.
Can you do that please?

USING is a variation of the ON keyword in join syntax. This link explains it in detail. In the example, the query
SELECT C.First_Name, C.Last_Name, O.title
FROM Employee AS C
LEFT JOIN job as O USING (ID);
is identical to
SELECT C.First_Name, C.Last_Name, O.title
FROM Employee AS C
LEFT JOIN job as O ON C.ID = O.ID;

It's used for JOINs:
MySQL: 12.2.8.1. JOIN Syntax
"The USING(column_list) clause names a list of columns that must exist in both tables. If tables a and b both contain columns c1, c2, and c3, the following join compares corresponding columns from the two tables."

It is used in JOINs, I think you can get here some more information about it.

Related

SQL inner join multiple tables with one query

I've a query like below,
SELECT
c.testID,
FROM a
INNER JOIN b ON a.id=b.ID
INNER JOIN c ON b.r_ID=c.id
WHERE c.test IS NOT NULL;
Can this query be optimized further?, I want inner join between three tables to happen only if it meets the where clause.
Where clause works as filter on the data what appears after all JOINs,
whereas if you use same restriction to JOIN clause itself then it will be optimized in sense of avoiding filter after join. That is, join on filtered data instead.
SELECT c.testID,
FROM a
INNER JOIN b ON a.id = b.ID
INNER JOIN c ON b.r_ID = c.id AND c.test IS NOT NULL;
Moreover, you must create an index for the column test in table c to speed up the query.
Also, learn EXPLAIN command to the queries for best results.
Try the following:
SELECT
c.testID
FROM c
INNER JOIN b ON c.test IS NOT NULL AND b.r_ID=c.testID
INNER JOIN a ON a.id=b.r_ID;
I changed the order of the joins and conditions so that the first statement to be evaluated is c.test IS NOT NULL
Disclaimer: You should use the explain command in order to see the execution.
I'm pretty sure that even the minor change I just did might have no difference due to the MySql optimizer that work on all queries.
See the MySQL Documentation: Optimizing Queries with EXPLAIN
Three queries Compared
Have a look at the following fiddle:
https://www.db-fiddle.com/f/fXsT8oMzJ1H31FwMHrxR3u/0
I ran three different queries and in the end, MySQL optimized and ran them the same way.
Three Queries:
EXPLAIN SELECT
c.testID
FROM c
INNER JOIN b ON c.test IS NOT NULL AND b.r_ID=c.testID
INNER JOIN a ON a.id=b.r_ID;
EXPLAIN SELECT c.testID
FROM a
INNER JOIN b ON a.id = b.r_id
INNER JOIN c ON b.r_ID = c.testID AND c.test IS NOT NULL;
EXPLAIN SELECT
c.testID
FROM a
INNER JOIN b ON a.id=b.r_ID
INNER JOIN c ON b.r_ID=c.testID
WHERE c.test IS NOT NULL;
All tables should have a PRIMARY KEY. Assuming that id is the PRIMARY KEY for the tables that it is in, then you need these secondary keys for maximal performance:
c: INDEX(test, test_id, id) -- `test` must be first
b: INDEX(r_ID)
Both of those are useful and "covering".
Another thing to note: b and a is virtually unused in the query, so you may as well write the query this way:
SELECT c.testID,
FROM c
WHERE c.test IS NOT NULL;
At that point, all you need is INDEX(test, testID).
I suspect you "simplified" your query by leaving out some uses of a and b. Well, I simplified it from there, just as the Optimizer should have done. (However, elimination of tables is an optimization that it does not do; it figures that is something the user would have done.)
On the other hand, b and a are not totally useless. The JOIN verify that there are corresponding rows, possibly many such rows, in those tables. Again, I think you had some other purpose.

What is the difference between JOIN and simple SELECT in MySQL?

I have two mySQL statements. First is:
SELECT o.OrderID, c.CustomerName, o.OrderDate
FROM Customers AS c, Orders AS o
WHERE c.CustomerID=o.CustomerID;
The second is:
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers
ON Orders.CustomerID=Customers.CustomerID;
Both produce the same result, but second doesn't contain reference on Customers table in FROM request.
My question is - what is the difference between these two sql statements? In which cases should I use JOIN and in which cases should I use simple SELECT from two tables?
They are the same except the second is easier to read, so you should use that one.
Those JOIN are different, although the result are the same.
The First one is CROSS JOIN and adds the condition in where, which is implicit CROSS JOIN
The second one is INNER JOIN
If you want to connect two tables I would use INNER JOIN instead of CROSS JOIN Because the intention of the inner join table is clearer

MySQL --- Explicit INNER JOIN with selection from multiple tables

Whenever I have a need to do an inner join where I have to select columns from multiple tables, I have got the syntax working correctly with implicit joins, without any difficulty. However, I have struggled to get it working with explicit inner joins.
Let me illustrate with an example from the MySQL World Database
My illustrative query, using implicit inner join, is as follows:
SELECT Name, Language, Percentage
FROM Country, CountryLanguage WHERE Code = CountryCode ;
This works as expected. I can have the columns in any order, from either table, without any issues.
I would like to have the explicit INNER JOIN version of the above query (using "INNER JOIN" and "ON").
You can simply replace the , in your implicit join with the word JOIN:
SELECT Name, Language, Percentage
FROM Country
JOIN CountryLanguage
WHERE Code = CountryCode
and the query will work fine. You can also replace WHERE with ON and again it will work fine. Finally if you want to explicitly name the tables where the columns come from (and this is the preferred approach), you would use:
SELECT c.Name, cl.Language, cl.Percentage
FROM Country c
JOIN CountryLanguage cl
ON c.Code = cl.CountryCode
Maybe it would be like
SELECT Name, Language, Percentage,
FROM Country
INNER JOIN CountryLanguage ON Country.Code = CountryLanguage.CountryCode

sql , two USING clauses in one statement

im just doing some sql exercises on w3 and wondering about the following statement
SELECT a.ord_no, a.purch_amt, b.cust_name, c.name,
FROM orders a
INNER JOIN customer b USING (customer_id)
INNER JOIN salesman c USING (salesman_id)
edit: i posted wrong testing results , statement doesnt work for reasons explained by answer from ScaisEdge.
Looking to your code
FROM orders a
INNER JOIN customer b USING (customer_id)
INNER JOIN salesman c USING (salesman_id)
seems that the using clause is ambigous when you use more then 2 tables
In your case the second using is for customer or orders .. ??
The sql engine can't define the correct one so you must use explicit on clause for avoid using ambiguity

Joining on derived column without using subquery

In MySQL I'm trying to join two tables on a derived column, something like this:
SELECT C.country,
IFNULL(C.preferred_city, C.default_city) AS best_city,
PC.postal_code
FROM Countries as C
INNER JOIN PostalCodes AS PC
ON best_city=PC.city
This of course does not work because best_city is outside the scope of the ON clause.
The only solution I could find was using a subquery (or is this considered a derived table? I'm fuzzy on the nomenclature):
SELECT BC.*, PC.postal_code
FROM (
SELECT country, IFNULL(preferred_city, default_city) AS best_city
FROM COUNTRIES
) AS BC
INNER JOIN PostalCodes AS PC
ON BC.best_city=PC.city
which works nicely from the shell. However, I'm trying to implement this as a view and it gives me the error: ERROR 1349: View's SELECT contains a subquery in the FROM clause
How can I rework this to join without using a subquery??
Thanks!
Try something like:
SELECT BC.*, PC.postal_code
FROM COUNTRIES BC
INNER JOIN PostalCodes AS PC
ON PC.city = IFNULL(preferred_city, default_city)