1.前言

  太久没有在数据库做一些复杂的sql了,基本上将数据库的查询逻辑全放在了Java里做,

一来呢,可以减轻数据库的负担,二来呢,在java写,逻辑感会更强,数据类型更丰富也容易操作。

  然而。。。面试却喜欢靠复杂的sql ,好吧,即便我不想,但复习一波还是免不了的。

常用的关系型数据库有 MySQL和Oracle 。Oracle 比较喜欢使用存储过程做业务 ,当然,MySQL也可以,但是没怎么用,

自从工程使用mybatis框架,就不再使用存储过程了,业务基本是增删改查,查询数据的逻辑都是从数据库取相应数据出来后用Java计算,

再从数据库获取最终想要的数据,本来是本着减轻数据库负担才这样做的,并发操作会用上积极锁【乐观锁】,因此也就不需要担心 脏数据问题。

  MySQL和Oracle的语法部分是不同的,有时候用着MySQL,写着写着就用上了Oracle的语法,还一脸懵逼的查了半天到底哪里错,不常使用的东西就是容易忘。

总结:
(1)Oracle 使用nvl() 函数,MySQL使用 ifnull() 函数 来对数据进行判断是否为空,
如果是空则使用替代的数据 ,参数一样 ,如if(x.age,0),意思是如果年龄字段为空则
输出 0 .
(2)sum()函数是运算函数,允许 加减乘除计算 ,如果要使用,则必须使用
group by 分组 ,限定好分组 sum获取的计算数据才不会错,否则将会导致全表计算在一起。
(3)avg()函数是计算平均数的,用法根据需要与 group by 分组配合使用,
如果是计算全表某字段的平均分,则不要使用。
(4)having 关键字可以筛选分组后的各组数据,也就是说可对分组完成后的数据做逻辑条件判断 ,与where类似,但是where无法这样使用,因为where关键字无法与聚合函数一起使用

2.复习题

数据库源码

/*
Navicat MySQL Data Transfer Source Server : cen
Source Server Version : 50528
Source Host : localhost:3306
Source Database : kktest Target Server Type : MYSQL
Target Server Version : 50528
File Encoding : 65001 Date: 2020-06-17 08:21:15
*/ SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Table structure for bjb
-- ----------------------------
DROP TABLE IF EXISTS `bjb`;
CREATE TABLE `bjb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of bjb
-- ----------------------------
INSERT INTO `bjb` VALUES ('1', '一班');
INSERT INTO `bjb` VALUES ('2', '2班');
INSERT INTO `bjb` VALUES ('3', '3班'); -- ----------------------------
-- Table structure for cjb
-- ----------------------------
DROP TABLE IF EXISTS `cjb`;
CREATE TABLE `cjb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_sx` int(11) DEFAULT NULL,
`yw` int(11) DEFAULT NULL,
`sx` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of cjb
-- ----------------------------
INSERT INTO `cjb` VALUES ('1', '1', '77', '67');
INSERT INTO `cjb` VALUES ('2', '2', '32', '27');
INSERT INTO `cjb` VALUES ('3', '3', '98', '78');
INSERT INTO `cjb` VALUES ('4', '4', '68', '63');
INSERT INTO `cjb` VALUES ('5', '5', '66', '77');
INSERT INTO `cjb` VALUES ('6', '6', '99', '88');
INSERT INTO `cjb` VALUES ('7', '7', '75', '45');
INSERT INTO `cjb` VALUES ('8', '8', '77', '88');
INSERT INTO `cjb` VALUES ('9', '9', '65', '81');
INSERT INTO `cjb` VALUES ('10', '10', '83', '89'); -- ----------------------------
-- Table structure for xsb
-- ----------------------------
DROP TABLE IF EXISTS `xsb`;
CREATE TABLE `xsb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`id_banji` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of xsb
-- ----------------------------
INSERT INTO `xsb` VALUES ('1', '岑', '1');
INSERT INTO `xsb` VALUES ('2', 'cen', '1');
INSERT INTO `xsb` VALUES ('3', 'y', '2');
INSERT INTO `xsb` VALUES ('4', 'u', '3');
INSERT INTO `xsb` VALUES ('5', 'yue', '2');
INSERT INTO `xsb` VALUES ('6', 'kk', '2');
INSERT INTO `xsb` VALUES ('7', 'tom', '1');
INSERT INTO `xsb` VALUES ('8', 'lili', '1');
INSERT INTO `xsb` VALUES ('9', 'kile', '3');
INSERT INTO `xsb` VALUES ('10', 'jack', '2');
INSERT INTO `xsb` VALUES ('11', 'hh', '2'); -- ----------------------------
-- Procedure structure for sp_add3
-- ----------------------------
DROP PROCEDURE IF EXISTS `sp_add3`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_add3`(a int, b int,out c int)
begin
set c=a+ b;
end
;;
DELIMITER ;

kktest.sql

学生表【字段意思:学生id、姓名、班级id】

班级表【字段意思:班级id、班级名称】

成绩表【字段意思:成绩id、学生id、语文成绩、数学成绩】

【注意:11号同学hh ,他没有成绩,他作弊被取消了考试资格,因此成绩表没有他的信息】

(1)查询所有学生的信息

写法一:

select x.id,x.name,b.name n from xsb x
left join bjb b on b.id = x.id_banji;

查询结果

写法二:

select x.id,x.name,b.name n2 from xsb x,bjb b
where b.id = x.id_banji;

查询结果与上图一样

(2)查询所有人的课程分数

写法一:【查询11号同学为null】

select x.name,b.name n ,c.yw ,c.sx from xsb x
left join bjb b on b.id = x.id_banji
left join cjb c on c.id_sx = x.id ;

查询结果

写法二:【查询11号同学为0】

select x.name,b.name n , ifnull(c.yw,0)  , ifnull(c.sx,0)  from xsb x
left join bjb b on b.id = x.id_banji
left join cjb c on c.id_sx = x.id ;

查询结果

写法三:【查询无11号同学】不使用left join会导致没有成绩的那个同学不显示,因为直接连表查询只会保留所有关联条件成立的数据

select x.name,b.name n , ifnull(c.yw,0)  , ifnull(c.sx,0)  from xsb x,bjb b,cjb c
WHERE b.id = x.id_banji
and c.id_sx = x.id ;

查询结果

(3)查询语文分数比“yue”的高的学生,【 如果是查询比“yue”的低, 不使用ifnull那么没有成绩的同学无法查看到】

select x.name,b.name n , ifnull(c.yw,0)  from xsb x
left join bjb b on b.id = x.id_banji
left join cjb c on c.id_sx = x.id
where ifnull(c.yw,0) >
(
select c.yw from cjb c
left join xsb x on c.id_sx = x.id
where x.name= "yue"
)

查询结果

(4)查询各科都合格【分数>=60分】的学生(姓名、语文分数、数学分数)

select x.name , c.yw ,c.sx
from xsb x
left join cjb c on c.id_sx =x.id
WHERE c.yw>60 and c.sx >60

打印结果

(5)查询总分数(语文+数学)>=150的学生信息(姓名、班级名称、总分数)

select x.name,b.name n ,
ifnull(c.yw,0) as "语文",ifnull(c.sx,0) as "数学",
#sum是运算函数 ,在里面可以做加减乘除
sum(ifnull(c.yw,0) + ifnull(c.sx,0)) as "总分"
from xsb x
left join bjb b on b.id = x.id_banji
left join cjb c on c.id_sx = x.id
where (ifnull(c.yw,0) +ifnull(c.sx,0)) >=150
#计算总分必须要分组,加上这个GROUP BY x.id,表示以一位学生为一组计算总分,否则会全部加在一起
GROUP BY x.id

查询结果

(6)查询没有参加考试【没有成绩表】的学生(姓名、班级名称)

写法一:

select x.name,b.name n   from xsb x
left join bjb b on b.id = x.id_banji
left join cjb c on c.id_sx = x.id
where x.id not in (select id_sx from cjb);

查询结果

写法二:

select x.name,b.name n  from xsb x ,bjb b ,cjb c
WHERE x.id_banji = b.id and x.id not in (select id_sx from cjb)
GROUP BY x.name,b.name ;

查询结果与上图一样

(7)假设分数>=60分合格,分析学生的成绩是否合格

select x.name,if(c.yw>=60,"合格","不合格") as "语文成绩" ,
if(c.sx>=60,"合格","不合格") as "数学成绩"
from xsb x
left join cjb c on c.id_sx = x.id

查询结果

(8)查询有挂科【分数<60分】现象的学生(姓名、语文分数、数学分数)

select x.name ,ifnull( c.yw ,0),ifnull(c.sx,0)
from xsb x
left join cjb c on c.id_sx =x.id
WHERE ifnull( c.yw ,0) <60 or ifnull(c.sx,0)<60;

查询结果

(9)查询所有班级的平均分数(班级编号、班级名称、语文平均分数、数学平均分数)

写法一:

select b.name , AVG(c.yw) as "语文平均分数" ,AVG(c.sx) as "数学平均分数" from xsb x
left join bjb b on b.id = x.id_banji
left join cjb c on c.id_sx = x.id
GROUP BY b.id ;

查询结果

写法二:【主从表换了没影响】

select b.name , AVG(c.yw) as "语文平均分数" ,AVG(c.sx) as "数学平均分数" from bjb b
left join xsb x on b.id = x.id_banji
left join cjb c on c.id_sx = x.id
GROUP BY b.id

查询结果与上图一样

(10)查询班级人数>=3的班级(班级编号、班级名称、人数)

select b.id ,b.name , count(x.id) as "人数"
from bjb b
left join xsb x on b.id = x.id_banji
#HAVING 子句可以让我们筛选分组后的各组数据。
group by b.id having count(x.id) >=3

查询结果

用一道题 来 复习 MySQL 的 复杂 sql 语句的更多相关文章

  1. MySQL 常用的sql语句小结(待续)

    mysql 常用的sql语句 1.查看数据库各个表中的记录数 USE information_schema; SELECT table_name,table_rows FROM tables WHER ...

  2. mysql使用基础 sql语句(一)

    csdn博文地址:mysql使用基础 sql语句(一)  点击进入 命令行输入mysql -u root -p,回车再输入密码,进入mysql. 终端命令以分号作为一条语句的结束,可分为多行输入,只需 ...

  3. 监控mysql执行的sql语句

    linux平台 监控mysql执行的sql语句   为了做好配合开发做性能和功能测试,方便监控正在执行的sql语句, 可以在/etc/mysqld中添加如下:  log =/usr/local/mys ...

  4. MySQL的常用SQL语句.md

    修改密码 这是常见的大家一般都要用的 首先     安装成功了打开cmd --> mysql -u root -p -->输入你的密码     修改mysql root用户密码    格式 ...

  5. mysql统计类似SQL语句查询次数

    mysql统计类似SQL语句查询次数 vc-mysql-sniffer 工具抓取的sql分析. 1.先用shell脚本把所有enter符号替换为null,再根据语句前后的字符分隔语句 grep -Ev ...

  6. MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause

    MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause 201 ...

  7. Oracle,SQL Server 数据库较MySql数据库,Sql语句差异

    原文:Oracle,SQL Server 数据库较MySql数据库,Sql语句差异 Oracle,SQL Server 数据库较MySql数据库,Sql语句差异 1.关系型数据库 百度百科 关系数据库 ...

  8. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  9. mysql(数据库,sql语句,普通查询)

    第1章 数据库 1.1 数据库概述 l 什么是数据库 数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作. l 什 ...

随机推荐

  1. 什么是maven(一)

    转自博主--一杯凉茶 我记得在搞懂maven之前看了几次重复的maven的教学视频.不知道是自己悟性太低还是怎么滴,就是搞不清楚,现在弄清楚了,基本上入门了.写该篇博文,就是为了帮助那些和我一样对于m ...

  2. 3.Vue.js-目录结构

    Vue.js 目录结构 上一章节中我们使用了 npm 安装项目,我们在 IDE(Eclipse.Atom等) 中打开该目录,结构如下所示: 目录解析 目录/文件 说明 build 项目构建(webpa ...

  3. 【C/C++】金币

    做了一下去年的题目,今年看起来就没这么难了 从上到下的可以从下到上考虑,会简单很多,dp入门 题目 金币 小招在玩一款游戏,在一个N层高的金字塔上,以金字塔顶为第一层,第i层有i个落点,每个落点有若干 ...

  4. 【C/C++】习题3-7 DNA/算法竞赛入门经典/数组与字符串

    [题目] 输入m组n长的DNA序列,要求找出和其他Hamming距离最小的那个序列,求其与其他的Hamming距离总和. 如果有多个序列,求字典序最小的. [注]这道题是我理解错误,不是找出输入的序列 ...

  5. 令无数程序员加班的 Log4j2 远程执行漏洞复现

    前情提要 Apache 存在 Log4j 远程代码执行漏洞,将给相关企业带来哪些影响?还有哪些信息值得关注? 构建maven项目引入Log4j2 编写 pom 文件 <?xml version= ...

  6. 『学了就忘』Linux系统管理 — 84、Linux中进程的管理

    目录 1.Linux系统中的信号 2.杀掉进程的命令 (1)kill命令 (2)killall命令 (3)pkill命令 1.Linux系统中的信号 Linux系统中可以识别的信号较多,我们可以使用命 ...

  7. bjdctf r2t3 onegadget

    没错,这就是一篇很水的随笔.... 两道很简单的题,先来看第一道.r2t3,保护检查了一下是只开启了堆栈不可执行. 简单看一下ida的伪代码. main函数让你输入一个name,然后会执行一个name ...

  8. Landsat 现有 Analysis Ready Data (ARD) 数据介绍

    Global Web-Enabled Landsat Data (GWELD)[1] NASA 原先的 Web-Enabled Landsat Data Conterminous U.S. Seaso ...

  9. GDAL重投影重采样像元配准对齐

    研究通常会涉及到多源数据,需要进行基于像元的运算,在此之前需要对数据进行地理配准.空间配准.重采样等操作.那么当不同来源,不同分辨率的数据重采样为同一空间分辨率之后,各个像元不一一对应,有偏移该怎么办 ...

  10. 升级过log4j,却还没搞懂log4j漏洞的本质?

    摘要:log4j远程代码漏洞问题被大范围曝光后已经有一段时间了,今天完整讲清JNDI和RMI以及该漏洞的深层原因. 本文分享自华为云社区<升级过log4j,却还没搞懂log4j漏洞的本质?为你完 ...