当前位置:网站首页>Index +sql exercise optimization

Index +sql exercise optimization

2022-06-27 07:44:00 Fairy wants carry

Catalog

Advantages and disadvantages

When to use the index

Expain Performance analysis

  Analysis field :

Insert 100w How to achieve the fastest data

 1. Create a function ( Randomly generate numbers and random names )

 2. Create stored procedures and insert data ( Use the above two functions to get the random number and name )

technological process :

 3. Create index

The execution of multi field index is shown in the figure

  practice

  How the index finds the data

matters needing attention

  A small summary

Some suggestions

Relational query

Association query instance  

Small conclusion of association query :

Correlation optimization test

The impact of indexes on grouped queries

Sorting and grouping optimization

  There is also a very optimized point ( Overlay index ):

Homework (sql practice + Optimize )


 

Advantages and disadvantages

Improve data retrieval efficiency through indexing , Reduce IO cost , But using indexes will also reduce the efficiency of updating , Each modification will cause the information in our index file to change , And memory consumption up

  An index can also be understood as a table , The index fields inside point to entity table records

When to use the index

  Frequently used as query criteria 、 Associated query 、 Group sorted 、 The only index

Expain Performance analysis

effect :

Use Explain Keywords can simulate the optimizer ( It's the one before Optimizer Optimizer ) perform SQL Query statement , obtain mysql How to deal with sql Of the statement , Analyze ( View execution plan )

Use :

  Analysis field :

id Represents an independent query , One sql The less you lie down, the better

 select_type

 type

The most important three :range、index、all

 key and key_len and rows

 key_len How to calculate index length

 EXTRA

Purpose : Reduce full table scanning , Increase performance

  Subquery (SUBQUERY):

  Range queries (DEPENDENT SUBQUERY)

  Unavailable cache queries :

 sql Not hit ,sql Dissimilarity ——> When a variable appears ,sql It must be different ;

  All problem :

  All table scan, Traverse the entire table to find the matching rows ;

  index Indexes

  appear index yes sql Index is used but not filtered by index , Generally, the overlay index is used or the index is used for sorting and grouping ;

  Range queries :

 group by Sort first and then group

  After using the index, it is found that the speed is 100 times optimized (reset cache)

  Two tables are associated with , Associated fields should be indexed

where The field after the condition is indexed

  Statistical quantity count(*):MyISAM Words , He counted the amount of data in the table ,InnoDB No statistics will really open the table for scanning

EXPLAIN SELECT * FROM t_dept

Field analytical :

 id It refers to the execution sequence ,type It refers to the yellow, red and black warnings ,key_len refer to where Condition field length ( The longer the length , The easier it is to hit ),rows The number of rows for the value ( Number of lines scanned physically , The less the better, the faster ),Extra Additional fields are generally viewed group by,other by, Relational query ; 


Insert 100w How to achieve the fastest data

1. We can 100w Insert statements to splice , Turn him into a sentence , It must be faster

2. We can cancel mysql Automatic submission of , because 100w Data submission 100w Times and submissions 1 Time

It must be different ;

3. Using multithreading

mysql Master-slave replication of

The master slave uses a binlog, There are common functions

 1. Create a function ( Randomly generate numbers and random names )

 

 2. Create stored procedures and insert data ( Use the above two functions to get the random number and name )

CREATE TABLE `dept` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `deptName` VARCHAR(30) DEFAULT NULL,
 `address` VARCHAR(40) DEFAULT NULL,
 ceo INT NULL ,
 PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
 
CREATE TABLE `emp` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `empno` INT NOT NULL ,
 `name` VARCHAR(20) DEFAULT NULL,
 `age` INT(3) DEFAULT NULL,
 `deptId` INT(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
 #CONSTRAINT `fk_dept_id` FOREIGN KEY (`deptId`) REFERENCES `t_dept` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

# Enable the user-defined function configuration 
SET GLOBAL log_bin_trust_function_creators=1;



 
 # Randomly generated string function 
DELIMITER $$
CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255)
BEGIN    
DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
 DECLARE return_str VARCHAR(255) DEFAULT '';
 DECLARE i INT DEFAULT 0;
 WHILE i < n DO  
 SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));  
 SET i = i + 1;
 END WHILE;
 RETURN return_str;
END $$
 
USE mydb
 
# Used to randomly generate number to number 
DELIMITER $$
CREATE FUNCTION  rand_num (from_num INT ,to_num INT) RETURNS INT(11)
BEGIN   
 DECLARE i INT DEFAULT 0;  
 SET i = FLOOR(from_num +RAND()*(to_num -from_num+1))   ;
RETURN i;  
 END$$ 
 
# If you want to delete 
#drop function rand_num;

 
# If you want to delete 
#drop function rand_string;


# Insert 500000 pieces of data 
DELIMITER $$
CREATE PROCEDURE  insert_emp(  START INT ,  max_num INT )
BEGIN  
DECLARE i INT DEFAULT 0;   
#set autocommit =0  hold autocommit Set to 0, Turn off auto submit   
 SET autocommit = 0;    
 REPEAT  
 SET i = i + 1;  
 INSERT INTO emp (empno, NAME ,age ,deptid ) VALUES ((START+i) ,rand_string(6)   , rand_num(30,50),rand_num(1,10000));  
 UNTIL i = max_num  
 END REPEAT;  
 COMMIT;  
 END$$ 
 
# Delete 
# DELIMITER ;
# drop PROCEDURE insert_emp;
 

 
# Execute stored procedures , Go to dept Add random data to table 
DELIMITER $$
CREATE PROCEDURE `insert_dept`(  max_num INT )
BEGIN  
DECLARE i INT DEFAULT 0;   
 SET autocommit = 0;    
 REPEAT  
 SET i = i + 1;  
 INSERT INTO dept ( deptname,address,ceo ) VALUES (rand_string(8),rand_string(10),rand_num(1,500000));  
 UNTIL i = max_num  
 END REPEAT;  
 COMMIT;  
 END$$
 
# Delete 
# DELIMITER ;
# drop PROCEDURE insert_dept;


# Insert 1w Data 
# Execute stored procedures , Go to dept Table to add 1 Ten thousand data 
DELIMITER ;
CALL insert_dept(10000); 


# Execute stored procedures , Go to emp Table to add 50 Ten thousand data 
DELIMITER ;
CALL insert_emp(100000,500000); 
 
SELECT COUNT(*) FROM emp;
SELECT COUNT(*) FROM dept;
 

  Like so much data , We need an index to query , We're going to do the next sql To delete the current sql The index of

technological process :

need mysql Acknowledge the string you extracted

1. Look at the index in the table

SHOW INDEX FROM t_emp; 

2. Our index is also a table , stay information In the database , The name is STATISTICS

  Look at the index table , The primary key index cannot be deleted

 3. Create index

Single field

Let's check , Find out explain Estimate 49w Multiple lines

EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.`age`=30;

CREATE INDEX idx_age ON emp(age);

  After index creation , Only 4w All right , Speed up

0.03->0.007

Multiple fields  

EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 AND deptid=4 AND emp.name = 'abcd';  
CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);

Speed by 0.082-> negligible

The execution of multi field index is shown in the figure

Best left prefix : Execute from left to right in order , Otherwise it will disconnect

 If the system often appears sql as follows :
  EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30   AND emp.name = 'abcd'   
 perhaps 
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.deptid=1   AND emp.name = 'abcd'   
  The original idx_age_deptid_name  Whether it can be used normally ?

The second one cannot be executed normally , Not following the order from left to right , Ring hit is required ——> At the same time, it also reflects the full value matching , Fields must correspond to indexes


  practice

# Execution deletion 
CALL proc_drop_index("mydb","emp");

# Query the specified index in the index table  ( Non primary key )
SELECT index_name FROM information_schema.`STATISTICS` WHERE TABLE_NAME='t_emp' 
AND TABLE_SCHEMA='mydb' AND INDEX_NAME <>'PRIMARY' AND SEQ_IN_INDEX=1;


EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.`age`=30; #0.03 0.007
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 AND deptid=4
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 AND deptid=4 AND emp.name = 'abcd';  

# Create index 
CREATE INDEX idx_age ON emp(age);
CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);

SHOW INDEX FROM emp; 

# Fuzzy query 
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.`name` LIKE 'abc%';#0.8->0.016

# This can lead to index invalidation , Don't use functions 
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE  LEFT(emp.`name`,3)='abc';#0.8

# Create index 
CREATE INDEX idx_name ON emp(NAME);

# Execution deletion 
CALL proc_drop_index("mydb","emp");
CALL proc_drop_index("mydb","dept");

# Range queries , The field index on the right side of the range is invalid ( The right side is judged according to the index )
 EXPLAIN SELECT SQL_NO_CACHE * FROM emp #0.5->0.052,type:range
 WHERE emp.age=30 AND emp.deptId>20 AND emp.name = 'abc' ; # Optimal efficiency 0.004

# Create index 
CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);
CREATE INDEX idx_age_deptid_name ON emp(age,NAME,deptid);


EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.`name` <> 'abc';

# Create index , For the above failure != Can cause indexes to fail 
CREATE INDEX idx_name ON emp(NAME);

EXPLAIN SELECT * FROM emp WHERE age IS NULL #0.2->0.001
  
# This is not It's going to fail   
EXPLAIN SELECT * FROM emp WHERE age IS NOT NULL;#0.04->0.009, Index failure ,type by ALL

# Create index 
CREATE INDEX idx_age ON emp(age);

# Our index structure of the balanced tree is based on a-z, If the initials are uncertain , The index will fail 
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.`name` LIKE '%abc%';#0.329->0.274

# Create index 
CREATE INDEX idx_name ON emp(NAME);	


# Execution deletion 
CALL proc_drop_index("mydb","emp");
CALL proc_drop_index("mydb","dept");


# Type conversion can also cause index invalidation 
# If you have several fields, you can index them 

  How the index finds the data

 (24 Bar message ) (3)MySQL How to pass 【 Indexes 】 Find one. 【 Real data 】_ A message from Gu Hong LWQ The blog of -CSDN Blog _mysql How to query by index

matters needing attention

Be careful sql To write , Prevent index invalidation  

  A small summary

 1. Remember the best left front rule

 2. You can't use functions :abs,max,<>....

 3. Out-of-service like Prefix %xxx wildcard

 4.is not null no way

 5. Nor can type conversion

Some suggestions

1. When selecting a composite index , We can put the fields with good filtering performance in the front of the index fields , Because it is filtered out to the next tree , Maybe there are fewer nodes , Even for 1, More efficient ;

2. When selecting Composite Index , Try to include where More fields after

3. Try to avoid index invalidation

Relational query

scene :

When two tables have no associated fields , And then it makes the association query , Both tables will be scanned globally , So the Cartesian product

How they relate to :

In the associated query scenario , We associate queries -> First, the data in the first row of the drive table will be scanned , Then scan the driven table according to the first row of data , The found data is combined into a row of data ;

Conclusion :

1. The drive table must be scanned globally , Driven tables are not necessarily , So we build the index on the driven table , The drive table must be completely scanned, so it doesn't matter whether the index is built or not ;

2. To improve efficiency , Our relatively small amount of data is best used as the driving table  

3. in addition ,inner join and left join Not quite the same. , stay inner join Next mysql Will automatically select the driven table , Rather than their relative position , yes According to the small result set as the driving table ;

Association query instance  

 Query the two tables by association  ->extra There are no associated fields between the two tables , Very slow to check , Descartes appears 
EXPLAIN SELECT * FROM class LEFT JOIN book ON class.`card`=book.`card`; 

# Create index , Here we usually index the driven table 
CREATE INDEX Y ON book(card);

# Execution deletion 
CALL proc_drop_index("mydb","book");
DROP INDEX Y ON book;
DROP INDEX X ON class;

# Create index 
ALTER TABLE class ADD INDEX X (card);

#inner join,mysql Choose which is the driven table ——> Judge according to the index , Whoever has an index is driven 


# Small data is the driving table , Short scanning time to improve efficiency 

# Please all dept Corresponding CEO name 

#1. Here you will find that it is a query ,mysql5.7 An optimization of ,c The table is the driving table , Our driven table is ab Virtual table 
# Virtual tables cannot create indexes , So an optimization opportunity will be wasted ,5.7 Where the update is 
EXPLAIN SELECT c.`name`,ab.name ceoname FROM t_emp c LEFT JOIN
(SELECT b.`id`,a.`name` FROM t_emp a INNER JOIN t_dept b ON a.`id`=b.`CEO`)ab
ON c.`deptld`=ab.id;


# obtain dept The leader of 
SELECT b.`id`,a.`name` FROM t_emp a INNER JOIN t_dept b ON a.`id`=b.`CEO`

#2. First, check the name and CEO
SELECT ab.name,c.`name` ceoname FROM
(SELECT a.`name`,b.`CEO` FROM t_emp a LEFT JOIN t_dept b ON a.`deptld`=b.`id`) ab 
LEFT JOIN t_emp c ON ab.ceo=c.`id`;


#3. The fastest , Directly related , You don't need to subquery to connect to the sect leader twice at a time ( Get the user's information for the first time , The second is based on CEO Screening )
EXPLAIN SELECT a.`name`,c.`name` ceoname FROM t_emp a 
LEFT JOIN t_dept b ON a.`deptld`=b.`id`
LEFT JOIN t_emp c ON b.`CEO`=c.`id`;

Small conclusion of association query :

1. We need to ensure that the driven table join And indexed

2.left join when , Select the small table as the driver

3.inner join: The small result set is used as the driving table

4. Subqueries should not be placed in the driver table , because 5.7 Pre virtual tables cannot be indexed , Will lead to reduced efficiency

5. If it can be directly related, it can be directly related

Correlation optimization test

There is obviously not The index cannot be used , Optimize -> Use left join Make association query , Then filter according to the conditions  

# At least two non leader sects ( The leader number first , Then, according to the leader's number, you can go to t_emp Intermediate investigation )
SELECT * FROM t_emp a WHERE a.id NOT IN
(SELECT b.CEO FROM t_dept b WHERE b.CEO IS NOT NULL);

# Optimize ( Get all the leaders first (left join), Then the bar filter )
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.id = b.CEO
WHERE b.id IS NULL;

The impact of indexes on grouped queries

(24 Bar message ) 【mysql Arrangement of knowledge points 】--- order by 、group by appear Using filesort A detailed explanation of why _nrsc The blog of -CSDN Blog _filesort reason

summary :

1. Group query order by Whether the field after can use the index -> It depends on whether the filter conditions are followed , If so, the index will take effect

2.order by The following sequence is very important , The order is different, the result is different , So it will not be optimized

3. If the fields are in ascending or descending order, the result will not be affected , If there is any inconsistency, it will affect the occurrence of using filesort

# Execution deletion 
CALL proc_drop_index("mydb","emp");
CALL proc_drop_index("mydb","dept");


# Group query 
CREATE INDEX idx_age_deptid_name ON emp (age,deptid,NAME)
CREATE INDEX idx_age_deptid_empno ON emp (age,deptid,empno); 
 
 
# Whether the following indexes can be used , Can you get rid of it? using filesort ,(order by If you want to use the index, you must filter the conditions )
EXPLAIN  SELECT SQL_NO_CACHE * FROM emp ORDER BY age,deptid; 
 
EXPLAIN  SELECT SQL_NO_CACHE * FROM emp ORDER BY age,deptid LIMIT 10; 
 

 # No filtering   No index 
 
 
EXPLAIN  SELECT * FROM emp WHERE age=45 ORDER BY deptid;
 
EXPLAIN  SELECT * FROM emp WHERE age=45 ORDER BY   deptid,NAME; 
 
EXPLAIN  SELECT * FROM emp WHERE age=45 ORDER BY  deptid,empno;
 
#deptid The field needs to be name front , This order is not optimized , Because the result will be affected ,order by The order of the following fields is very important  
EXPLAIN  SELECT * FROM emp WHERE age=45 ORDER BY  NAME,deptid;
 
EXPLAIN SELECT * FROM emp WHERE deptid=45 ORDER BY age;
 
 
 
 
# Wrong order , No sorting is required , It can be in descending or ascending order , In this case , Changing the order will not affect the result 
 
 
EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY  deptid DESC, NAME DESC ;
 
     
 
EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY  deptid ASC, NAME DESC ;
 
# In the opposite direction   No sorting is required , One rise and one fall cannot be indexed :Using filesort

Sorting and grouping optimization

mysql The index selection will be optimized , Choose an index that you think is the fastest

If the field is not on the index column ,filesort There are two algorithms

1. Two way sorting : Just scan the disk twice , First, scan everything and put it on the disk , After scanning, sort the contents of the disk ( That is, read the line pointer and order by Column ), Scan the disk twice ,IO Very time consuming

2. One way sorting : Read the index column of the query from disk , And then according to order by The query , He puts the contents of each read into memory , Less IO Loss of

 group by And other by The difference is that

group by You can use indexes without restrictions ,other by No filtering, no indexing

  There is also a very optimized point ( Overlay index ):

Fuzzy queries did not appear before like %xx、is not、other by xxx All these will lead to index invalidation , We can restrict the content of the query , No more select * , Instead, fields limit , In this way, the index can be matched according to the field , To improve efficiency ;

CREATE INDEX idx_id_age_deptid ON emp(id,age,deptid);

# The query contents can be indexed 
EXPLAIN SELECT SQL_NO_CACHE NAME FROM emp WHERE age IS NOT NULL;

EXPLAIN SELECT * FROM emp WHERE NAME LIKE '%abc';

EXPLAIN SELECT SQL_NO_CACHE id,age,deptid FROM emp WHERE NAME LIKE '%abc';

# Look at the index 
SHOW INDEX FROM emp;

Homework (sql practice + Optimize )

Be careful :Group by After setting the field of , front select The field of can only contain Group by Content of and function content , Otherwise, an error will be reported

EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE age =30 AND empno <101000 ORDER BY NAME ;#0.729

# Execution deletion 
CALL proc_drop_index("mydb","emp");
CALL proc_drop_index("mydb","dept");

# Index , First priority idx_age_empno The index of ,mysql Will choose the best index 
CREATE INDEX idx_age_empno ON emp(age,empno);
CREATE INDEX idx_age_name ON emp (age,NAME);
CREATE INDEX idx_age ON emp(age);
CREATE INDEX idx_name ON emp(NAME);
CREATE INDEX idx_id_age_deptid ON emp(id,age,deptid);

# The query contents can be indexed 
EXPLAIN SELECT SQL_NO_CACHE NAME FROM emp WHERE age IS NOT NULL;

EXPLAIN SELECT * FROM emp WHERE NAME LIKE '%abc';

EXPLAIN SELECT SQL_NO_CACHE id,age,deptid FROM emp WHERE NAME LIKE '%abc';

# Look at the index 
SHOW INDEX FROM emp;


#1. Ask for information that my younger brother is younger than the sect leader 
SELECT a.name FROM t_emp a 
LEFT JOIN t_dept b ON a.`deptld`=b.id
LEFT JOIN t_emp c ON b.CEO=c.`id`
WHERE c.`age`<a.`age`;

# Optimize 
EXPLAIN SELECT SQL_NO_CACHE a.`name`,a.`age`,c.`name`,c.`age` FROM emp a 
LEFT JOIN dept b ON a.`deptId`=b.`id`
LEFT JOIN emp c ON b.`ceo`=c.`id`
WHERE c.`age`<a.`age`;


#2. List those who are younger than the average age of the guild ( Get the personnel information of the Department group first )
SELECT  c.`name`,c.`age` FROM t_emp c INNER JOIN
(SELECT a.`deptld`,AVG(a.`age`) avgage FROM t_emp a WHERE a.`deptld` IS NOT NULL
GROUP BY a.`deptld`)aa
ON c.`deptld`=aa.deptld
WHERE c.`age`<aa.avgage;


# Optimize , Use this subquery as the driver table 
# Because subquery 5.7 You cannot have an index before the version , So we use it as a driver table , In this way, the non driven table can be indexed 
EXPLAIN SELECT SQL_NO_CACHE c.`name`,c.`age`,aa.avgage FROM emp c 
INNER JOIN
(SELECT a.deptId,AVG(a.age)avgage FROM emp a WHERE a.deptId IS NOT NULL
GROUP BY a.deptId)aa
ON c.`deptId`=aa.deptId
WHERE c.`age`<aa.avgage;


# Create index 
CREATE INDEX idx_deptId ON emp(deptId);
CREATE INDEX idx_deptId_age ON emp(deptId,age);


#3. List at least 2 Age >40 Year old members of the sect  (select Get the quantity , Must be group by 了 )
#( First, group according to the sect  -> Then filter to get >40 Number of employees aged  —> Finally, make a judgment )
SELECT b.`deptName`,b.`id`,COUNT(*) FROM t_emp a
INNER JOIN t_dept b ON a.`deptld`=b.`id`
WHERE a.`age`>40
GROUP BY b.`deptName`,b.`id`
HAVING COUNT(*)>=2;


# Optimize 
EXPLAIN SELECT SQL_NO_CACHE b.`deptName`,b.`id`,COUNT(*) FROM dept b 
STRAIGHT_JOIN emp a ON a.`deptId`=b.`id`
WHERE a.`age`>40
GROUP BY b.`deptName`,b.`id`
HAVING COUNT(*)>=2;

# Index 
CREATE INDEX idx_deptName ON dept(deptName);
CREATE INDEX idx_deptId_age ON emp(deptId,age);


#4. Non leader ( First, check all the gangs with gangs , Then extract CEO, then not in)
SELECT * FROM t_emp a WHERE a.`id` NOT IN
(SELECT b.`CEO` FROM t_dept b WHERE b.`CEO` IS NOT NULL)
;

SELECT * FROM t_emp 
SELECT * FROM t_dept 

# Optimize :(1. Get the information of non leader sect members , Use left outer Association query , If there is no match in the sect table, you will null, So we need to b.id is null)
SELECT * FROM t_emp a 
LEFT JOIN t_dept b ON a.`id`=b.`CEO`
WHERE b.`id` IS NULL;

SELECT c.deptName,c.id,COUNT(*) 
FROM t_emp a INNER JOIN t_dept c ON a.`deptld`=c.id
LEFT JOIN t_dept b ON a.`id`=b.`CEO`
WHERE b.`id` IS NULL
GROUP BY c.deptName,c.id
HAVING COUNT(*)>=2
;

#5. Get all the members of the gang -> Get the name of the local gang and id-> In association once , Remove the leader , Leave the information of non leader ( Using the property of left outer )
# To get the quantity , So grouping 
EXPLAIN SELECT SQL_NO_CACHE c.`deptName`,c.`id`,COUNT(*) FROM emp a 
INNER JOIN dept c ON a.`deptId`=c.`id`
LEFT JOIN dept b ON a.`id`=b.`CEO`
WHERE b.`id` IS NULL
GROUP BY c.`deptName`,c.`id`
HAVING COUNT(*)>=2;


# Create index 
CREATE INDEX idx_deptName ON dept(deptName);
CREATE INDEX idx_deptId ON emp(deptId);
CREATE INDEX idx_CEO ON dept(CEO);


#6. List all people , And add a column to indicate whether it is the leader , If it is a remark, it is ——>case when  Judge 
# Then we use the left outer property b Of id->is null then xxx Judge 
SELECT a.`name`,a.`age`,b.`deptName`,(CASE WHEN b.id IS NULL THEN ' no ' ELSE ' yes ' END)' Is it the leader '
FROM t_emp a 
LEFT JOIN t_dept b ON a.`id`=b.`CEO`; 


#7. List all sects , And note , Average age >50 Old bird , Otherwise, it will be a rookie 
SELECT b.`deptName`,b.`id`,IF(AVG(a.`age`)>50,' veteran ',' rookie ')' veteran or rookie ' 
FROM t_emp a
INNER JOIN t_dept b ON a.`deptld`=b.`id`
GROUP BY b.`deptName`,b.`id`;


#8. Show the oldest person of each sect (-> First get the maximum age and group according to the sect -> Then we can get the oldest person by associating the character table )
SELECT c.`name`,c.`age`,aa.maxage FROM t_emp c INNER JOIN 
(SELECT a.`deptld`,MAX(a.`age`)maxage 
FROM t_emp a WHERE a.`deptld` IS NOT NULL
GROUP BY a.`deptld`)aa
ON c.`deptId`=aa.deptld AND c.`age`=aa.maxage;


#9. Ask the third oldest person of each sect (w Write the wrong )
SELECT a.`age`,a.`name`,a.`deptld` FROM t_emp a ORDER BY a.`age` DESC 
LEFT JOIN(
SELECT a.`id` FROM t_emp a INNER JOIN t_dept b ON a.`deptld`=b.id
)aa ON a.`deptld`=aa.id;# Here is the wrong grouping , Group the original plan and then limit complete 


原网站

版权声明
本文为[Fairy wants carry]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/178/202206270734411668.html