[置顶] MySQL---查询2

查询

(续)

一个完整的SQL语句:
 select 
  分组依据的列名,
  其他的列,
  组函数
 from 
  表名1(子查询)
 join 
  表名2
 on 
  表的联接条件
 left join 
  表名3
 on (外联接时on条件必须有)
  表的联接条件
 where 
  过滤条件 
 group by 
  分组依据的列名
 having 
  组函数 比较表达式(分组结果的过滤)
 order by 
  排序依据的列 desc
 limit 
  略过的记录数,最终显示限制的记录数

DISTINCT---去重
小例子:
	查询员工的部门ID, 跨库查询(加上限定)
		SELECT 
			DISTINCT department_id
		FROM
			company.employees ;
	全球有多少不同的大洲
		SELECT 
			DISTINCT continent
		FROM
			world.country;
	
	在City表中有多少不同的地区。
		SELECT 
			DISTINCT District
		FROM
			city;

联接查询

有时候查询需要将两个表或者多个表连接然后进行查询。

联接:笛卡尔乘积, 逗号联接
语法描述:
SELECT
   *
  FROM 表名1,表名2;
小例子:
	将country2表和city2表联接
		SELECT
			 * 
		FROM <pre class="sql" name="code">有条件的联接,数据有意义,过滤
		SELECT
			 * 
		FROM 
			city2, country2
		WHERE 
			countrycode = code;

country2, city2;
 
   

内联接(和逗号联接一样)
语法描述:
SELECT
     FROM
     表1
 [INNER] JOIN
     表2
ON
     联接条件
JOIN
    表3
ON
    联接条件
 WHERE
    普通过滤条件
小例子:
	查询城市人口数大于100万的城市名称和所属国家
		SELECT 
			ci.name city,
			co.name country ,
			ci.population cityPop
		FROM 
			city2 ci
		[INNER] JOIN
			country2 co
		ON
			ci.countrycode = co.code 
		WHERE 
			ci.population > 1000000;
	
	注意事项:
		内联虽然和逗号一样, 优先使用内联
		INNER关键字可以省略
		ON和WHERE虽然可以混用, 但是不建议
		ON 后面最好是联接条件
		WHERE 后面是普通过滤条件
		查询结果就是满足联接条件的行
	小例子:表的联接可以不止一个
	查询一下国家和首都,只显示首都人口大于500万的国家
		SELECT 
			co.name country,
			ci.name capital,
			ci.populatiON,
			cl.language
		FROM
			country co 
		JOIN
			city ci 
		ON 
			co.capital = ci.id
		JOIN 
			countrylanguage cl
		ON 
			co.code = cl.countrycode 
		WHERE 
			ci.populatiON > 5000000
			AND
			cl.isofficial = 'T';

外联接:保证某个表的数据的完整性
语法描述:
SELECT
  FROM
   表1
  LEFT [OUTER] JOIN
   表2
  ON
   联接条件
  WHERE
   普通过滤条件
小例子:
	查询所有国家和首都
		SELECT 
			co.name country,
			ci.name capital
		FROM 
			country co 
		LEFT JOIN 
			city ci
		ON 
			co.capital = ci.id;
	
	查询所有国家及官方语言
		SELECT 
			country.name,
			cl.language,
			cl.isofficial
		FROM 
			country 
		LEFT JOIN
			countrylanguage cl 
		ON 
			country.code = cl.countrycode
		WHERE 
				cl.isofficial = 'T'
			or 
				cl.isofficial is null
	
	哪些国家没有首都
		SELECT 
			co.name country,
			ci.name capital,
			co.capital,
			ci.id
		FROM 
			country co 
		LEFT JOIN 
			city ci
		ON 
			co.capital = ci.id
		WHERE 
			ci.name is null;

单行函数
 常用的单行函数使用方式及效果
 LOWER('SQL COURSE') ----> sql course 将目标字符串转为小写
 UPPER('SQL Course')----> SQL COURSE 将目标字符串转为大写
 CONCAT('Hello', 'World')---->HelloWorld 联接两个字符串
 SUBSTR('HelloWorld',1,5)---->Hello  获取子串
 LENGTH('HelloWorld')---->10   获取字符串的长度
 INSTR('HelloWorld', 'W')---->6  在目标位置插入字符
 LPAD(salary,10,'*')---->*****24000  右对齐填充
 RPAD(salary, 10, '*')---->24000*****  左对齐填充
 TRIM(‘H’ FROM 'HelloWorld')----->elloWorld 截取字符串
 REPLACE('abcd','b','m')---->amcd  替换目标字符

 ROUND(45.926, 2)---->45.93 四舍五入
 TRUNC(45.926, 2)---->45.92  截断
 MOD(1600, 300)---->100  求余
小例子:
	单行函数
		SELECT 
			CONCAT(first_name, last_name) name,
			lpad(salary, 10, '0')
		FROM 
			company.employees;

	把所有国家和首都名使用:连接起来,并全部转为大写显示
		SELECT 
			UPPER(CONCAT(co.name, ' : ', ci.name))
		FROM 
			country co 
		LEFT JOIN 
			city ci
		ON 
			co.capital = ci.id

组函数
     AVG(列名)
     MAX(列名)
     SUM(列名)
      MIN(列名)
小例子:
	查询所有员工的平均工资和最大最小值,求和.
		SELECT 
			AVG(salary) 平均工资, 
			MAX(salary) 最高工资,
				MIN(salary) minSalary, 
			SUM(salary) sumSalary
		FROM   
			company.employees;
	
	查看表中的记录数,不要使用具体列名,除非是主键
		SELECT 
			count(*)
		FROM
			country;

	在统计计算中拒绝出现代表个体的信息
		SELECT 
			--last_name,
			MIN(salary) 最低平资 
		FROM   
			company.employees;

		SELECT 
			--name,
			max(populatiON)
		FROM
			country
		WHERE 
			cONtinent = 'europe';


GROUP BY和组函数配合使用进行查询

语法描述:
       SELECT
             分组条件,
              组函数(这里的组函数是作用于某一组成员)
       FROM
             表名
       GROUP BY
             分组条件

小例子:
	查询每个部门的平均工资
		SELECT   
			department_id, AVG(salary)
		FROM     
			company.employees
		GROUP BY 
			department_id;

	查询各大洲的平均寿命和最少人口数
		SELECT 
			continent,
			avg(lifeexpectancy) avgLife,
			min(population) minPop
		FROM 
			country 
		GROUP BY 
			continent


HAVING
      对分组结果进行过滤. 不能使用WHERE 
        HAVING只能对分组结果进行过滤

小例子:
	查询部门平均工资大于9000的部门id
		SELECT   
			department_id, AVG(salary)
		FROM     
			company.employees
		GROUP BY 
			department_id
		HAVING 
			avg(salary) > 9000;

	查询哪些国家的语言超过10种要求显示国家名称
		SELECT 
			co.name,
			count(cl.language) langs
		FROM 
			countrylanguage cl 
		right JOIN 
			country co 
		ON 
			cl.countrycode = co.code 
		GROUP BY 
			co.name
		HAVING 
			langs > 10 
		ORDER BY 
			langs;


当上述关键字参与查询是,提供一种思考思路。
 1) 判断需要从哪个表中取数据 确定FROM
 2) 一张表够吗? 如果不够 JOIN
 3) 需要保证某表数据完整吗? 如果需要 考虑外联, 继续考虑左右的问题
 4) 联接条件的确定 ON
 5) 判断是否需要虚表的中的所有数据, 如果不需要 WHERE
 6) 是否需要分组, 如果需要 GROUP BY, 进一步判断分组依据的列名.
 7) 把分组依据的列名放在SELECT后面
 8) 继续考虑SELECT究竟要选择哪些列(组函数)
 9) 分组的结果是都需要吗? 如果不需要 HAVING过滤
 10)是否需要对最终的显示排序 ORDER BY


小例子:
	查询中国的所有城市
		FROM
			city
		WHERE  
			countrycode = 'chn';
	查询中国的城市个数
		SELECT 
			countrycode,
			count(*)
		FROM
			city 
		GROUP BY
			countrycode
		HAVING 
			countrycode = 'chn';

	列出不同的国家(country code)有居民超过7,000,000的城市, 它们有多少?
		SELECT 
			countrycode,
			count(*)
		FROM 
			city 
		WHERE 
			population > 7000000
		GROUP BY 
			countrycode;

	查询中国的每个省的总城市数量和总人口数
		SELECT 
			district,
			count(*),
			sum(population)
		FROM
			city 
		WHERE 
			countrycode = 'chn'
		GROUP BY 
			district
		ORDER BY 
			sum(population) desc;
	
		SELECT
			countrycode,
			district,
			count(*),
			sum(population)
		FROM 
			city 
		GROUP BY 
			district
		HAVING
			countrycode = 'chn'
		ORDER BY 
			sum(population) desc;

	每个国家各有多少种语言
		SELECT 
		countrycode,
		count(*)
		FROM 
			countrylanguage 
		GROUP BY 
			countrycode

	美国有多少种语言
		SELECT 
			countrycode,
			count(*)
		FROM 
			countrylanguage 
		WHERE 
			countrycode='usa'

	Sweden国家说的是什么语言?
		SELECT 
			a.name,
			b.language
		FROM
			country  a 
		JOIN 
			countrylanguage b 
		ON 
			a.code = b.countrycode 
		WHERE 
			a.name = 'Sweden';


	哪些国家没有列出任何使用语言?
		SELECT
			a.name
		FROM 
			country a 
		LEFT JOIN 
			countrylanguage b
		ON 
			a.code = b.countrycode 
		WHERE 
			b.language is null;
	
		SELECT 
			a.name,
			count(language)
		FROM
			country a
		LEFT JOIN 
			countrylanguage b
		ON 
			a.code = b.countrycode
		GROUP BY 
			a.name 
		HAVING 
			count(language) = 0;


	列出在城市表中80%人口居住在城市的国家
		SELECT 
			a.name,
			(sum(b.populatiON) / a.populatiON) AS rate
		FROM 
			country a 
		JOIN 
			city b 
		ON
			a.code = b.countrycode 
		GROUP BY 
			a.name 
		HAVING 
			rate >= 0.8;

子查询

语法描述:
         select
              分组依据的列名,
              其他的列,
              组函数
        from
              表名1(子查询)
        join
              表名2
       on
              表的联接条件
       left join
              表名3
       on (外联接时on条件必须有)
               表的联接条件
       where
                过滤条件
       group by
               分组依据的列名
        having
               组函数 比较表达式(分组结果的过滤)
        order by
               排序依据的列 desc
         limit 
               略过的记录数,最终显示限制的记录数 

 可以用一个子查询替代上边的的表名。
 子查询,将查询操作嵌套在另一个查询操作中。先执行子查询,再执行外查询
小例子:
	查询谁的工资比'Abel'的工资高
		SELECT last_name
		FROM   company.employees
		WHERE  salary >
			       (SELECT salary
				FROM   company.employees
				WHERE  last_name = 'Abel');
				
	查询城市人口最多的城市名称
		SELECT 
			name 
		FROM 
			city 
		WHERE 
			population = (SELECT max(population) FROM city);
	
	查询最发达的国家 
		SELECT 
			name 
		FROM 
			country 
		WHERE 
			gnp = (SELECT max(gnp) FROM country);
	







你可能感兴趣的:(查询)