Java cultivation program -- the 68th day of learning punch in
Java (punch in the 68th day)
MySQL multi table connection query (MySQL 99)
Yesterday, we shared the multi table MySQL l92 syntax of MySQL. The disadvantage of this syntax is to mix the multi table connection conditions with the common filter conditions. At the same time, we introduced the equivalent connection, that is, the connection conditions are equal conditions
mysql> SELECT -> f.fruits_name,c.language -> FROM -> fruits f -> JOIN -> culture c -> ON -> f.fruits_origin = c.location; +-------------+----------+ | fruits_name | language | +-------------+----------+ | Grape | Shandong Dialect | | Apple | Shandong Dialect | | Banana | Hainan Dialect | +-------------+----------+ 3 rows in set (0.01 sec)
Next, we will introduce the non equivalent connection of inner connection
Non equivalent connection of inner connection
The non equivalent connection of inner connection means that the connection conditions of two tables are no longer equal conditions, but other conditions
That is, the statement after the keyword ON is a non equivalent condition
Here is an example. For example, if two of them rank the price in the fruits table in the cfeng library, the non equivalent condition will be used
mysql> SELECT -> f.fruits_name 'Fruit name',f.fruits_price 'Fruit price',g.grade 'Price grade' -> FROM -> fruits f -> JOIN -> fruitsgrade g -> ON -> f.fruits_price BETWEEN g.lowpri AND g.highpri; +----------+----------+----------+ | Fruit name | Fruit price | Price grade | +----------+----------+----------+ | Grape | 3.7 | commonly | | Apple | 2.8 | cheap | | Banana | 6 | expensive | +----------+----------+----------+ 3 rows in set (0.00 sec)
It can be seen that the condition is not an equal quantity relationship, and the JOIN is the same as the INNER JOIN
Self connection of internal connection [the key is to see two tables]
For example, here is an employee table, which contains the employee's id, name and leader's id. now it is required to look up the table to get the name of each employee's superior leader
The solution is to treat one table as two tables
Therefore, the solution to this problem is to treat it as two tables in the future. One table is the employee table and the other is the leader table. The query is an equivalent query. The mgl of the employee table and the id of the leader table are equal as the query criteria
Here is the original watch
mysql> SELECT -> * -> FROM -> emp; +----+-------+-------+ | id | name | splid | +----+-------+-------+ | 1 | zhang | 4 | | 2 | wang | 3 | | 3 | liu | 4 | | 4 | huang | 5 | | 5 | hu | 0 | +----+-------+-------+ 5 rows in set (0.00 sec)
It is treated as an equivalent query. When joining, it is also the same table, which can be distinguished by aliases
mysql> SELECT -> e.name 'Employee name',b.name 'Leader name' -> FROM -> emp e -> JOIN -> emp b -> ON -> e.splid = b.id; //The two fields are the same +----------+----------+ | Employee name | Leader name | +----------+----------+ | wang | liu | | liu | huang | | zhang | huang | | huang | hu | +----------+----------+ 4 rows in set (0.00 sec)
Here, we alias the employee table e and the leader table b; but they are all tables emp
The above example is the inner connection. Note that there is one less query record than the table
External connection LEFT RIGHT [OUTER can be omitted]
Two tables connected internally are equal, and two tables connected externally are primary and secondary
LEFT OUTER RIGHT OUTER
Any left connection has the writing method of right connection, and the right connection is the same
- LEFT regards the table on the LEFT of the JOIN keyword as the main table, mainly to query all the data in the main table, but to query the right table
- RIGHT regards the table on the RIGHT of the JOIN keyword as the main table, mainly to query all the data in the main table, but to query the left table
In fact, it is simpler to select a main table. The privilege of the main table is not only to display the matched data, but also to display the unmatched data (that is, to display all data)
The characteristic of inner connection is that only the data that can completely match this condition can be queried
For example, the inner connection of the above fruit
+----------+----------+ | location | language | +----------+----------+ | Sichuan | Sichuan dialect | | Shandong | Shandong Dialect | | Hainan | Hainan Dialect | +----------+----------+
This is the culture table. There are three rows of records to match
Then after using the SQL statement
+-------------+----------+ | fruits_name | language | +-------------+----------+ | Grape | Shandong Dialect | | Apple | Shandong Dialect | | Banana | Hainan Dialect | +-------------+----------+ 3 rows in set (0.01 sec)
You can see that the final display result does not contain the first row record of the culture table, which is caused by the fact that only the query data that meets the query conditions can be queried
What if you want to query the data without matching here?
At this time, the external connection should be used
Syntax format of external connection
SELECT ...... FROM table1 RIGHT JOIN table2 ......
This is a right JOIN, which means that there is no query result, and no matching data in the right table will be displayed, that is, the table after the JOIN
The above query is just that the JOIN table has data and remains
mysql> SELECT -> f.fruits_name,c.language -> FROM -> fruits f -> RIGHT JOIN -> culture c -> ON -> f.fruits_origin = c.location; +-------------+----------+ | fruits_name | language | +-------------+----------+ | NULL | Sichuan dialect | | Apple | Shandong Dialect | | Grape | Shandong Dialect | | Banana | Hainan Dialect | +-------------+----------+ 4 rows in set (0.01 sec)
It can be seen that there is one more row of data than the previous query, that is, the first row of data in the culture table that does not match
The second is LEFT JOIN. The LEFT JOIN keyword is LEFT, and the data not matched in the table on the LEFT of the JOIN will be displayed additionally, which is also different from the table above the JOIN
SELECT ...... FROM table1 LEFT JOIN table2 ......
The example here is to reverse the order of the two columns in the above table and query fruits_name by language
mysql> SELECT -> c.language,f.fruits_name -> FROM -> culture c -> LEFT JOIN -> fruits f -> ON -> f.fruits_origin = c.location; +----------+-------------+ | language | fruits_name | +----------+-------------+ | Sichuan dialect | NULL | | Shandong Dialect | Apple | | Shandong Dialect | Grape | | Hainan Dialect | Banana | +----------+-------------+ 4 rows in set (0.00 sec)
The number of external connection query results must be > = the number of internal connection query results. If the mapping of two tables is bijection, the equal sign holds
- When querying the leader's name above, a record is missing because some data do not match. You can use external connection. For example, it is required to query the leader's name of all employees
It can be seen from the requirements that all employees are emphasized, so the employee table is the main table
mysql> SELECT -> e.name 'Employee name',b.name 'Leader name' -> FROM -> emp e -> LEFT JOIN -> emp b -> ON -> e.splid = b.id; +----------+----------+ | Employee name | Leader name | +----------+----------+ | zhang | huang | | wang | liu | | liu | huang | | huang | hu | | hu | NULL | +----------+----------+ 5 rows in set (0.00 sec)
This queries all data, including NULL
Here, the left connection is used at the same time
Connection of multiple tables
The above is about the connection of two tables. How to connect multiple tables
To put it bluntly, it is to JOIN ON many times
Basic format
SELECT ...... FROM table_a JOIN table_b ON a Table and b Table connection conditions JOIN table_c ON a Table and c Table connection conditions JOIN table_d ON a Table and d Table connection conditions
Note that you should not bypass yourself here. The connection conditions here are all for querying the fields of table a, so they are the connection conditions between table a and other tables
For example, the fruits table, the culture table and the fruits grade table are queried together, one time equivalent connection and one time non equivalent connection
mysql> SELECT -> f.fruits_name 'Fruit name',c.language 'Local dialect',g.grade 'Price grade' -> FROM -> fruits f -> JOIN -> culture c -> ON -> f.fruits_origin = c.location -> JOIN -> fruitsgrade g -> ON -> f.fruits_price BETWEEN g.lowpri AND g.highpri; +----------+----------+----------+ | Fruit name | Local dialect | Price grade | +----------+----------+----------+ | Grape | Shandong Dialect | commonly | | Apple | Shandong Dialect | cheap | | Banana | Hainan Dialect | expensive | +----------+----------+----------+ 3 rows in set (0.01 sec)
It can be understood that the culture table is connected first, and then another table is connected
In multi table connection, internal and external connections can be used at the same time
Even if one keeps adding JOIN and ON, it can also use self connection at the same time
Subquery
-
A subquery is a subquery in which a SELECT statement is nested in a SELECT statement, because the keyword of the query is SELECT
-
Where subqueries can appear
SELECT ......(SELECT) FROM ...... (SELECT) WHERE ...... (SELECT) //That is, sub queries can appear after SELECT, FROM and WHERE
Subquery in WHERE clause
Previously, when sharing grouping functions and multiline functions, it was mentioned that grouping returns cannot be used directly in the WHERE clause, because GROUP BY is executed after WHERE and before SELECT. Grouping functions cannot be used before there is no grouping
For example, query all the data of the city with the lowest population in the city table
mysql> SELECT -> * -> FROM -> city -> WHERE -> Population = MIN(Population); ERROR 1111 (HY000): Invalid use of group function
This will report an error: invalid use of grouping function
Therefore, the correct idea is to find out the minimum population first, and then query the city according to the minimum population
1. SELECT MIN(Population) FROM city; 2. SELECT * FROM city WHERE Population = min;
Then merge, that is, replace min with the above statement
SELECT * FROM city WHERE Population = (SELECT MIn(Population) FROM city);
You can see if it can be used after nesting
mysql> SELECT -> * -> FROM -> city -> WHERE -> Population = (SELECT MIN(Population) FROM city); +------+-----------+-------------+----------+------------+ | ID | Name | CountryCode | District | Population | +------+-----------+-------------+----------+------------+ | 2912 | Adamstown | PCN | – | 42 | +------+-----------+-------------+----------+------------+ 1 row in set (0.01 sec)
Nested statements are written in one line to facilitate nesting
The order of sub query is to execute the sub query first before the parent query. Here, execute the query statement in parentheses before executing the outer statement
Subquery of FROM clause
For the sub query after FROM, you can treat the results of the sub query as a temporary table
In fact, it is not difficult to understand that from is to obtain the table, WHERE is to filter, and the sub query behind from is of course a temporary table
Give me a case
- Find the population level of the average population of each country code in the top 100 cities in the city table?
The query target here can also be divided into two steps
1.Query the average population of each country code in the top 100 cities SELECT CountryCode,AVG(Population) FROM city WHERE ID <= 100 GROUP BY CountryCode 2.Query the population level corresponding to the average population of each country code The average population queried here forms a temporary table temp,Combine the table with populationgrade Connection acquisition level SELECT temp.CountryCode,temp.AVG(Population),g.grade FROM temp JOIN populationgrade g ON temp.temp.AVG(Population) BETWEEN g.lowpop AND g.highpop
In this way, you can see that you can put the above query statement in the following temp position and give it an alias
mysql> SELECT -> c.CountryCode 'Country code',c.AVG(Population) 'Average population',g.grade 'Population level' -> FROM -> (SELECT CountryCode,AVG(Population) FROM city WHERE ID <= 100 GROUP BY CountryCode) c -> JOIN -> populationgrade g -> ON -> c.AVG(Population) BETWEEN g.lowpop AND g.highpop; ERROR 1630 (42000): FUNCTION c.AVG does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual
The reason for the error is that the AVG function in the following ON does not exist, and SQL will treat it as a function, so the error is reported. The solution here is to alias the fields in the above sub query
mysql> SELECT -> c.CountryCode 'Country code',c.pop 'Average population',g.grade 'Population level' -> FROM -> (SELECT CountryCode,AVG(Population) AS pop FROM city WHERE ID <= 100 GROUP BY CountryCode) c -> JOIN -> populationgrade g -> ON -> c.pop BETWEEN g.lowpop AND g.highpop; +------+-------------+----------+ | Country code | Average population | Population level | +------+-------------+----------+ | AFG | 583025.0000 | Densely populated | | NLD | 185001.7500 | Normal population | | ANT | 2345.0000 | sparse population | | ALB | 270000.0000 | Normal population | | DZA | 288454.3889 | Normal population | | ASM | 3761.5000 | sparse population | | AND | 21189.0000 | Normal population | | AGO | 512320.0000 | Densely populated | | AIA | 778.0000 | sparse population | | ATG | 24000.0000 | Normal population | | ARE | 345667.2000 | Densely populated | | ARG | 513810.6250 | Densely populated | +------+-------------+----------+ 12 rows in set (0.00 sec)
SELECT sub sentence query
mysql> SELECT -> f.fruits_name,(SELECT c.language FROM culture c WHERE c.location = f.fruits_origin) -> FROM -> fruits f; +-------------+-----------------------------------------------------------------------+ | fruits_name | (SELECT c.language FROM culture c WHERE c.location = f.fruits_origin) | +-------------+-----------------------------------------------------------------------+ | Grape | Shandong Dialect | | Apple | Shandong Dialect | | Banana | Hainan Dialect | +-------------+-----------------------------------------------------------------------+ 3 rows in set (0.00 sec)
It is not recommended here. In fact, it is a table connection. The problem is that the results of sub queries are chaotic if they are not a field
Therefore, the previous two sub queries are mainly used
That's all for today. There will be more dry goods tomorrow~ 🌳