Learning MySQL database (twelve) - grouping queries HAVING

MySQL learn column is continuously updated in :)

Grouping queries

Recall that in our case on the article: database learning MySQL (XI) - Statistics function
turns out that we are FROM employeescarried out within the scope of such a statistical average, etc. to get maximum value, but in real life, always need grouping query , such as my statistics store marketing income more months, if not group, you need to use IF crazy judge, the most frightening is the longer, the more you IF conditional sentence, out of control
then we need to give him a packet for each the same operation as packets.

We will change a little table like this:
Here Insert Picture Description

USE data1;
SELECT 
  CONCAT(`last_name`,'-',`first_name`) 名字,
  `salary` 基本工资,
  YEAR(IFNULL(`hiredate`, 0)) 入职时间,
  CASE
    WHEN YEAR(`hiredate`) < 1996 
    THEN `salary` * (1+0.6+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 1997 AND 2000 
    THEN `salary` * (1+0.4+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 2001 AND 2010 
    THEN `salary` * (1+0.2+IFNULL(`commission_pct`, 0))
    WHEN YEAR(`hiredate`) BETWEEN 2011 AND 2014 
    THEN `salary` * (1+0.1+IFNULL(`commission_pct`, 0))
    ELSE `salary` * (1+0.0+IFNULL(`commission_pct`, 0))
  END AS 最终工资 
FROM
  employees 
ORDER BY 入职时间 ASC ;

But I'm curious, final salary and entry time there is little to do, so I will entry time to a GROUP BY, for each entry time, take the highest wages to see the effect:
Here Insert Picture Description

USE data1;
SELECT 
  CONCAT(`last_name`,'-',`first_name`) 名字,
  `salary` 基本工资,
  YEAR(IFNULL(`hiredate`, 0)) 入职时间,
  MAX(CASE
    WHEN YEAR(`hiredate`) < 1996 
    THEN `salary` * (1+0.6+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 1997 AND 2000 
    THEN `salary` * (1+0.4+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 2001 AND 2010 
    THEN `salary` * (1+0.2+IFNULL(`commission_pct`, 0))
    WHEN YEAR(`hiredate`) BETWEEN 2011 AND 2014 
    THEN `salary` * (1+0.1+IFNULL(`commission_pct`, 0))
    ELSE `salary` * (1+0.0+IFNULL(`commission_pct`, 0))
  END) AS 每组最高_最终工资 
FROM
  employees 
GROUP BY 入职时间
ORDER BY 入职时间 ASC ;

In fact, feel less relevant after all, the oldest of the highest wages may be the boss QAQ :)
nothing to MAXchange the AVGlook effect:
Here Insert Picture Description
high youngest group of wages, the middle number of the most miserable, the oldest of a group of very comfortable :)

WHERE statement where the problem

GROUP BY 入职时间And the whole sentence WHERE ORDER BY FROMis the same as an additional SELECT statement, the equivalent of adding a filter Fliter since then are "tied" Additional statement casually put how I like it?
You can try, but the result is GG
the WHERE filter for FROM employees in the original table this range (can be loaded to force points: domain), it is best to put FROM employeesthe rear end, make an additional filter,
in general, WHERE can only be for a column (or property and said column) WHERE condition of a filter that's it
but sometimes we do not get the desired parameters in the properties of the original table column (or columns) which,
if only shining original properties , do some math, are not the problem, just as before:
Here Insert Picture Description
the case I would like to table this before the
Here Insert Picture Description
screening of the final average salary> 8000 Object instance (ie a row), how to do?
Analysis you are actually in the entry for the years 1992, 1996, 2000, etc. of a table inside a small, statistically some of the statistics (mean value). We do screening again from an average Zhi, in fact, it is already another table to do wherethe
I guess someone would write:

USE data1;
SELECT 
  CONCAT(`last_name`,'-',`first_name`) 名字,
  `salary` 基本工资,
  YEAR(IFNULL(`hiredate`, 0)) 入职时间,
  AVG(CASE
    WHEN YEAR(`hiredate`) < 1996 
    THEN `salary` * (1+0.6+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 1997 AND 2000 
    THEN `salary` * (1+0.4+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 2001 AND 2010 
    THEN `salary` * (1+0.2+IFNULL(`commission_pct`, 0))
    WHEN YEAR(`hiredate`) BETWEEN 2011 AND 2014 
    THEN `salary` * (1+0.1+IFNULL(`commission_pct`, 0))
    ELSE `salary` * (1+0.0+IFNULL(`commission_pct`, 0))
  END) AS 每组平均_最终工资 
FROM
  employees 

WHERE AVG(CASE
    WHEN YEAR(`hiredate`) < 1996 
    THEN `salary` * (1+0.6+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 1997 AND 2000 
    THEN `salary` * (1+0.4+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 2001 AND 2010 
    THEN `salary` * (1+0.2+IFNULL(`commission_pct`, 0))
    WHEN YEAR(`hiredate`) BETWEEN 2011 AND 2014 
    THEN `salary` * (1+0.1+IFNULL(`commission_pct`, 0))
    ELSE `salary` * (1+0.0+IFNULL(`commission_pct`, 0))
  END) > 8000
GROUP BY 入职时间
ORDER BY 入职时间 ASC ;

Then harvested:
Here Insert Picture Description
error reason is clear: This is not the original table the original table, it should be said, we have to determine new property "_ final average salary", not the kind from the original table, directly apply a mathematical algebraic came out of , must be grouped again statistics. That is, the data source is not the original table .
Then WHERE this meaningless - he could do nothing on the table after a new packet, so we welcomed theHAVING

HAVING

The above correct wording should be:

USE data1;
SELECT 
  CONCAT(`last_name`,'-',`first_name`) 名字,
  `salary` 基本工资,
  YEAR(IFNULL(`hiredate`, 0)) 入职时间,
  AVG(CASE
    WHEN YEAR(`hiredate`) < 1996 
    THEN `salary` * (1+0.6+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 1997 AND 2000 
    THEN `salary` * (1+0.4+IFNULL(`commission_pct`, 0)) 
    WHEN YEAR(`hiredate`) BETWEEN 2001 AND 2010 
    THEN `salary` * (1+0.2+IFNULL(`commission_pct`, 0))
    WHEN YEAR(`hiredate`) BETWEEN 2011 AND 2014 
    THEN `salary` * (1+0.1+IFNULL(`commission_pct`, 0))
    ELSE `salary` * (1+0.0+IFNULL(`commission_pct`, 0))
  END) AS 每组平均_最终工资 
FROM
  employees 
GROUP BY 入职时间
HAVING 每组平均_最终工资  > 8000
ORDER BY 入职时间 ASC ;

ORDER BYAny position , that is, additional products, because both the scope of the original table or our new table grouping range can be used.
The HAVINGgeneral on the GROUPback, on a similar WHEREin FROMthe same back

to sum up

WHERE ago packet screening
HAVING screening grouped
in order to improve query performance, it is recommended multi-screened before grouping

expand

We from WHEREthe horizontal expansion is HAVING
from the front of the packet FROM employeesexpansion transverse GROUP BYgrouped
less visible HAVING similar WHERE properties, can accept the function return value filter such as:
HAVING CHAR_LENGTH(job.id)
the same: may be some mathematical algebra The data packet, then the packet the easiest way to:
GROUP BY job.id+1
orGROUP BY CHAR_LENGTH(job.id)

(Do not remember CHAR_LENGTH()the comrades here can be sent to: MySQL database Learning (nine) - Mathematical Functions String Functions )

Next stop:

Published 15 original articles · won praise 12 · views 1377

Guess you like

Origin blog.csdn.net/weixin_43178828/article/details/104084720