1. 程式人生 > 其它 >python入門學習篇三十三

python入門學習篇三十三

查詢關鍵字之having過濾

功能上having與where是一模一樣的
但是使用位置上有所不同
    where在分組之前使用
    having在分組之後使用
 
# 1.統計各部門年齡在30歲以上的員工平均工資,並且保留平均工資大於10000的部門
# 1.先篩選出所有30歲以上的員工
    select * from emp where age>30;
# 2.然後再按照部門分組
    '''SQL語句的查詢結構我們也可以直接看成是一張表'''
    select post,avg(salary) from emp where age>30 group by post;
# 3.分組之後做過濾操作
select post,avg(salary) from emp where age>30 group by post having avg(salary)>10000 ;

查詢關鍵字之distinct去重

去重有一個非常嚴格的前提條件 資料必須是完全一樣
    如果資料帶有主鍵那麼肯定無法去重
select distinct age from emp;

查詢關鍵字之order by排序

select * from emp order by salary;  # 預設是升序
select * from emp order by salary asc;  #
升序關鍵字 可以不寫 select * from emp order by salary desc; # 降序 # 排序也可以指定多個欄位 select * from emp order by age desc,salary asc; # 統計各部門年齡在10歲以上的員工平均工資,並且保留平均工資大於1000的部門,然後對平均工資進行排序 select post,avg(salary) from emp where age>10 group by post having avg(salary)>1000 order by avg(salary);

查詢關鍵字之limit分頁

用來限制資料的展示條數
select * from emp limit 5;  # 前五條
select * from emp limit 5,5;  # 起始位置、條數

# 查詢工資最高的人的詳細資訊
    # 先按照工資排序 然後限制展示條數
select * from emp order by salary desc limit 1;

查詢關鍵字之regexp正則

正則表示式
    用一些特殊符號的組合去字串中篩選出符合條件的資料
       
select * from emp where name regexp '^j.*(n|y)$';
# '^j.*(n|y)$'  j開頭 中間無所謂 n或者y結尾

多表查詢思想

1.子查詢
    分步解決問題
    將一條SQL語句的查詢結果用括號括起來當作另外一條SQL語句的查詢條件
 
2.連表操作
    先將所有需要用到的表拼接到一起(一張表)
    然後就是轉換成單表查詢

前期表準備

#建表
create table dep(
id int primary key auto_increment,
name varchar(20) 
);

create table emp(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') not null default 'male',
age int,
dep_id int
);

#插入資料
insert into dep values
(200,'技術'),
(201,'人力資源'),
(202,'銷售'),
(203,'運營'),
(205,'公關');

insert into emp(name,sex,age,dep_id) values
('jason','male',18,200),
('egon','female',48,201),
('kevin','male',18,201),
('nick','male',28,202),
('owen','male',18,203),
('jerry','female',18,204);

子查詢

# 查詢egon所在的部門名稱
    # 第一步 先獲取jason所在的部門id
    select dep_id from emp where name='jason';
       # 第二步 根據id號去部門表中篩選
    select * from dep where id = 200;
    # 完整句式
    select * from dep where id=(select dep_id from emp where name='jason');

連表操作

# 前戲(瞭解)
select * from emp,dep;
# 基於上表篩選資料(瞭解)
    '''為了避免欄位衝突 可以在欄位名前面加表名明確'''
select * from emp,dep where emp.dep_id=dep.id;


########################掌握############################
inner join    內連線    拼接公共的部分
    select * from emp inner join dep on emp.dep_id=dep.id;
left join    左連線 以左表為基準展示所有資料 沒有的null填充
    select * from emp left join dep on emp.dep_id=dep.id;
right join    右連線 以右表為基準展示所有資料 沒有的null填充
    select * from emp right join dep on emp.dep_id=dep.id;

    
    
    
union    全連線
    select * from emp left join dep on emp.dep_id=dep.id
    union
    select * from emp right join dep on emp.dep_id=dep.id;

Navicat視覺化軟體

可以充當很多資料庫軟體的客戶端 封裝了很多快捷方法

該軟體預設也是收費的 需要破解
正版不破解免費試用14天
破解版(老版本):https://pan.baidu.com/s/1bpo5mqj

1.下載與安裝
2.使用方法
    建立庫 表 記錄
        注意主鍵
     外來鍵欄位
    逆向資料庫到模型
    轉儲SQL檔案
      查詢

SQL檔案

/*
 資料匯入:
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50624
 Source Host           : localhost
 Source Database       : sqlexam

 Target Server Type    : MySQL
 Target Server Version : 50624
 File Encoding         : utf-8

 Date: 10/21/2016 06:46:46 AM
*/

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `class`
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `caption` varchar(32) NOT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `class`
-- ----------------------------
BEGIN;
INSERT INTO `class` VALUES ('1', '三年二班'), ('2', '三年三班'), ('3', '一年二班'), ('4', '二年九班');
COMMIT;

-- ----------------------------
--  Table structure for `course`
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `cname` varchar(32) NOT NULL,
  `teacher_id` int(11) NOT NULL,
  PRIMARY KEY (`cid`),
  KEY `fk_course_teacher` (`teacher_id`),
  CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `course`
-- ----------------------------
BEGIN;
INSERT INTO `course` VALUES ('1', '生物', '1'), ('2', '物理', '2'), ('3', '體育', '3'), ('4', '美術', '2');
COMMIT;

-- ----------------------------
--  Table structure for `score`
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `student_id` int(11) NOT NULL,
  `course_id` int(11) NOT NULL,
  `num` int(11) NOT NULL,
  PRIMARY KEY (`sid`),
  KEY `fk_score_student` (`student_id`),
  KEY `fk_score_course` (`course_id`),
  CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`),
  CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `score`
-- ----------------------------
BEGIN;
INSERT INTO `score` VALUES ('1', '1', '1', '10'), ('2', '1', '2', '9'), ('5', '1', '4', '66'), ('6', '2', '1', '8'), ('8', '2', '3', '68'), ('9', '2', '4', '99'), ('10', '3', '1', '77'), ('11', '3', '2', '66'), ('12', '3', '3', '87'), ('13', '3', '4', '99'), ('14', '4', '1', '79'), ('15', '4', '2', '11'), ('16', '4', '3', '67'), ('17', '4', '4', '100'), ('18', '5', '1', '79'), ('19', '5', '2', '11'), ('20', '5', '3', '67'), ('21', '5', '4', '100'), ('22', '6', '1', '9'), ('23', '6', '2', '100'), ('24', '6', '3', '67'), ('25', '6', '4', '100'), ('26', '7', '1', '9'), ('27', '7', '2', '100'), ('28', '7', '3', '67'), ('29', '7', '4', '88'), ('30', '8', '1', '9'), ('31', '8', '2', '100'), ('32', '8', '3', '67'), ('33', '8', '4', '88'), ('34', '9', '1', '91'), ('35', '9', '2', '88'), ('36', '9', '3', '67'), ('37', '9', '4', '22'), ('38', '10', '1', '90'), ('39', '10', '2', '77'), ('40', '10', '3', '43'), ('41', '10', '4', '87'), ('42', '11', '1', '90'), ('43', '11', '2', '77'), ('44', '11', '3', '43'), ('45', '11', '4', '87'), ('46', '12', '1', '90'), ('47', '12', '2', '77'), ('48', '12', '3', '43'), ('49', '12', '4', '87'), ('52', '13', '3', '87');
COMMIT;

-- ----------------------------
--  Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `gender` char(1) NOT NULL,
  `class_id` int(11) NOT NULL,
  `sname` varchar(32) NOT NULL,
  PRIMARY KEY (`sid`),
  KEY `fk_class` (`class_id`),
  CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `student`
-- ----------------------------
BEGIN;
INSERT INTO `student` VALUES ('1', '', '1', '理解'), ('2', '', '1', '鋼蛋'), ('3', '', '1', '張三'), ('4', '', '1', '張一'), ('5', '', '1', '張二'), ('6', '', '1', '張四'), ('7', '', '2', '鐵錘'), ('8', '', '2', '李三'), ('9', '', '2', '李一'), ('10', '', '2', '李二'), ('11', '', '2', '李四'), ('12', '', '3', '如花'), ('13', '', '3', '劉三'), ('14', '', '3', '劉一'), ('15', '', '3', '劉二'), ('16', '', '3', '劉四');
COMMIT;

-- ----------------------------
--  Table structure for `teacher`
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `tid` int(11) NOT NULL AUTO_INCREMENT,
  `tname` varchar(32) NOT NULL,
  PRIMARY KEY (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `teacher`
-- ----------------------------
BEGIN;
INSERT INTO `teacher` VALUES ('1', '張磊老師'), ('2', '李平老師'), ('3', '劉海燕老師'), ('4', '朱雲海老師'), ('5', '李傑老師');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

多表查詢題

1、 查詢所有的課程的名稱以及對應的任課老師姓名
4、 查詢平均成績大於八十分的同學的姓名和平均成績
7、 查詢沒有報李平老師課的學生姓名
8、 查詢沒有同時選修物理課程和體育課程的學生姓名
9、 查詢掛科超過兩門(包括兩門)的學生姓名和班級

#####################關鍵字習慣都用大寫###############################
# 建議:在書寫SQL語句的時候一定不要想著一次性成功 寫一點看一點再寫一點  慢慢拼湊起來
-- 1、 查詢所有的課程的名稱以及對應的任課老師姓名
# 1.先明確需要的表    course表 teacher表
--     select * from course;
--     select * from teacher;
# 2.連表操作 明確欄位
-- SELECT
--     course.cname,
--     teacher.tname
-- FROM
--     course
--     INNER JOIN teacher ON course.teacher_id = teacher.tid;
-- 4、 查詢平均成績大於八十分的同學的姓名和平均成績
# 1.先檢視成績表 
--     select * from score;
# 2.求所有學生的平均成績
--     select score.student_id,avg(num) from score group by score.student_id;
# 3.篩選出大於80分
--     select score.student_id,avg(num) as 'avg_num' from score group by score.student_id having avg(num)>80
--     ;
# 4.學生表與上述查詢出來的表連線
-- SELECT
--     student.sname,
--     t1.avg_num 
-- FROM
--     student
--     INNER JOIN ( SELECT score.student_id, avg( num ) AS 'avg_num' FROM score GROUP BY score.student_id HAVING avg( num )> 80 ) AS t1 ON student.sid = t1.student_id;
-- 7、 查詢沒有報李平老師課的學生姓名
# 1.正向思路:課下可以嘗試一下
# 2.反向思路:先找所有報了李平老師課程的學生 再取反
# 1.先查詢李平老師教授的課程id號
-- select tid from teacher WHERE tname='李平老師';
-- select cid from course where teacher_id in (select tid from teacher WHERE tname='李平老師');
# 2.去成績表中篩選出所有報了李平老師課程的學生id號
-- select distinct student_id from score where course_id in (select cid from course where teacher_id in (select tid from teacher WHERE tname='李平老師')); 
# 3.去學生表中 取反獲取沒有報李平老師課程的學生姓名
-- SELECT
--     sname 
-- FROM
--     student 
-- WHERE
--     sid NOT IN (
--     SELECT DISTINCT
--         student_id 
--     FROM
--         score 
--     WHERE
--         course_id IN (
--         SELECT
--             cid 
--         FROM
--             course 
--         WHERE
--         teacher_id IN ( SELECT tid FROM teacher WHERE tname = '李平老師' )));
-- 8、 查詢沒有同時選修物理課程和體育課程的學生姓名(只要報了一門的 兩門和都不報都不要)
# 1.先查詢物理 和 體育課程的id號
--     select cid from course where cname in ('物理','體育');
# 2.去成績表中先篩選出所有報了課程的資料(報了一門 報了兩門)
-- select * from score where course_id in (select cid from course where cname in ('物理','體育'));
# 3.按照學生id分組 統計每個學生報了的課程數目
-- select student_id from score where course_id in (select cid from course where cname in ('物理','體育'))
--     group by student_id
--     having count(course_id) = 1
-- ;
# 4.去學生表中根據id獲取學生姓名
-- SELECT
--     sname 
-- FROM
--     student 
-- WHERE
--     sid IN (
--     SELECT
--         student_id 
--     FROM
--         score 
--     WHERE
--         course_id IN (
--         SELECT
--             cid 
--         FROM
--             course 
--         WHERE
--         cname IN ( '物理', '體育' ))
--     group by student_id
--     having count(course_id) = 1);
-- 9、 查詢掛科超過兩門(包括兩門)的學生姓名和班級
# 1.先去成績表中 篩選出分數小於60分的資料
-- select * from score where num<60;
# 2.按照學生id分組 然後統計個數
-- select student_id from score where num<60 group by student_id
--     having count(num) >= 2
-- ;
# 3.將班級表與學生表拼接起來
SELECT
    class.caption,
    student.sname 
FROM
    class
    INNER JOIN student ON class.cid = student.class_id 
WHERE
    student.sid IN ( SELECT student_id FROM score WHERE num < 60 GROUP BY student_id HAVING count( num ) >= 2 );

搜尋

複製