mysql建表規則和基本使用語法


數據庫的設計范式數據庫的設計范式

  1. 要求:每一個分量必須是不可分的數據項。

    特點:

    1)有主鍵,且主鍵不能為空。

    2)字段不能再分。

     

    2.第二范式(2NF)

    要求:在范式一的基礎上,且每一個非主屬性完全函數依賴於主鍵。

    特點:

    1)滿足第一范式。

    2)表中的每一個非主屬性,必須完全依賴於本表主鍵。

    3)只有當一個表中,主鍵由兩個或以上的屬性組成的時候,才會出現不符合第二范式的情況。(如果出現不完全依賴那么只能發生在聯合主鍵的情況下。

3.第三范式(3NF)

要求:在第二范式的基礎上,且消除傳遞依賴性1)滿足第二范式

2)所有的非主鍵列依賴於主鍵列

注:3NF是對字段冗余性的約束,即任何字段不能由其他字段派生出來,它要求字段沒有冗余,但是沒有數據冗余的數據庫並不一定是最好的數據庫,所以有沒有冗余的設計,要綜合來考慮

 

-----mysql的查詢語句練習

 

學生表 student 學號 姓名  性別 出生年月日  所在班級
create table student(
  sno varchar(20) primary key,
      sname varchar(20) not null,
      ssex varchar(12) not null,
      sbirthday datetime,
      cla int(12)
  );
insert into student values("101","曾華","男","1977-09-01","95033");
insert into student values("102","匡明","男","1975-10-02","95031");
insert into student values("103","王麗","女","1976-01-23","95033");
insert into student values("105","匡yi明","男","1975-10-02","95031");
insert into student values("104","王er麗","女","1976-01-23","95033");
insert into student values("106","陸君","男","1974-06-03","95031");

--課程表 course 課程號 課程名稱 教師編號
表的約束--外鍵約束 foreign key reference
1 外鍵約束
一個表中某字段的值,受另一張表中某個字段的限制
主表(父表):提供數據的表
從表(子表):外鍵所在的表(引用主表中唯一性字段(主健,唯一)的值)
外鍵的值只能是主表中對應字段的值或者為null
foreign key references 主表(字段) --無名
constraint 約束名 foreign key references 主表(字段) -- 有名
foreign key references 主表(字段)  
constraint 約束名 foreign key references 主表(字段)
---------------------------------------
       create table course(
          cno varchar(20) primary key,
          cname varchar(20) not null,
          tno varchar(20) not null,
           foreign key(tno) references teacher(tno)

      );
       
insert into course values("3-105","計算機導論","825");
insert into course values("6-166","數字電路","856");
insert into course values("9-888","高等數學","831");
教師表 teacher 教師編號 教師名字 教師性別 出生年月日 職稱所在部門

create table teacher(
  tno varchar(20) primary key,
      tname varchar(20) not null,
      tsex varchar(10) not null,
      tbirthday datetime,
      prof varchar(20) not null,
      depart varchar(20) not null
  );
   insert into teacher values("804","李誠","男","1958-12-02","副教授","計算機系");
    insert into teacher values("856","張旭","男","1969-03-12","講師","電子工程系");
    insert into teacher values("825","王萍","女","1972-05-05","助教","計算機系");
    insert into teacher values("831","劉冰","女","1977-08-14","副教授","電子工程系");

– 成績表
– Score
– 學號
– 課程號
– 成績
-----------drop table score;
create table score(
sno varchar(20) not null,
  cno varchar(20) not null,
  grade decimal,
   foreign key(sno) references student(sno),
   foreign key(cno) references course(cno),
   primary key(sno,cno)
);
insert into score values("103","3-105","92");
insert into score values("103","6-166","85");
insert into score values("103","9-888","86");
insert into score values("105","3-105","88");
insert into score values("105","6-166","79");
insert into score values("105","9-888","75");
insert into score values("106","3-105","76");
insert into score values("106","6-166","81");
insert into score values("106","9-888","68");


 

sql 查詢語句
select * from student; 查詢student中的所有數據
select sname from student; 查詢student中的sname字段的值
select distinct depart from teacher; 查詢教師所有的單位既不重復的depart的值 -- distinct 去重
-- 查詢score表中的成績在60-80的所有記錄。
-- 查詢區間 between...and
select * from score where 60<grade<80;
select * from score where grade between 60 and 80;
-- 查詢 score 表中成績為85,86或88的紀錄。
-- 表示或者的關系查詢 in
select * from score where grade in(85,86,88);
mysql> select * from score where grade in(85,86,88);
      +-----+-------+-------+
      | sno | cno   | grade |
      +-----+-------+-------+
      | 103 | 6-166 |    85 |
      | 103 | 9-888 |    86 |
      | 105 | 3-105 |    88 |
      +-----+-------+-------+
       3 rows in set (0.00 sec)
       
-- 查詢student表中'96031'班或性別為女的同學紀錄
-- or表示或者
select * from student where class='95031' or ssex='女';
-- 以cla降序查詢student表中的所有記錄。
-- 升序order by asc 降序 order by desc
select * from student order by cla desc;
-- 以cno升序,degree降序查詢score 表中的所有記錄
select * from score order by cno asc,grade desc;
mysql> select * from score order by cno asc,grade desc;
      +-----+-------+-------+
      | sno | cno   | grade |
      +-----+-------+-------+
      | 103 | 3-105 |    92 |
      | 105 | 3-105 |    88 |
      | 106 | 3-105 |    76 |
      | 103 | 6-166 |    85 |
      | 106 | 6-166 |    81 |
      | 105 | 6-166 |    79 |
      | 103 | 9-888 |    86 |
      | 105 | 9-888 |    75 |
      | 106 | 9-888 |    68 |
      +-----+-------+-------+
       9 rows in set (0.00 sec)
-- 查詢'95031'班的學生人數。
-- 統計count
select count(*) from student where cla='95031';
      mysql> select count(*) from student where cla='95031';
          +----------+
          | count(*) |
          +----------+
          |        3 |
          +----------+
           1 row in set (0.00 sec)
   
-- 查詢score表中的最高分的學生學號和課程號。(子查詢或者排序)
-- 分析:找到最高分 select max(grade) from score;
-- 找到最高分的sno,cno
       select sno,cno from score where grade=(select max(grade) from score);
   -- 排序分析:limit 0,1 0表示開始索引,1表示取幾個
  -- select sno,cno,grade from score order by grade;
  -- select sno,cno,grade from score order by grade desc limit 0,1;
          mysql> select sno,cno from score where grade=(select max(grade) from score);
      +-----+-------+
      | sno | cno   |
      +-----+-------+
      | 103 | 3-105 |
      +-----+-------+
       1 row in set (0.00 sec)

-- 查詢每門課的平均成績
-- avg(grade)
  select avg(grade) from score where cno='9-888';
          mysql> select avg(grade) from score where cno='9-888';
          +------------+
          | avg(grade) |
          +------------+
          |    76.3333 |
          +------------+
           1 row in set (0.00 sec)
  -- 查詢每門課
  -- group by 分組
  select cno,avg(grade) from score group by cno;
mysql> select cno,avg(grade) from score group by cno;
      +-------+------------+
      | cno   | avg(grade) |
      +-------+------------+
      | 3-105 |    85.3333 |
      | 6-166 |    81.6667 |
      | 9-888 |    76.3333 |
      +-------+------------+
       3 rows in set (0.00 sec)
       
-- 查詢score表中至少有2名學生選修的並以3開頭的平均分數
-- where、聚合函數、having 在from后面的執行順序:
-- where>聚合函數(sum,min,max,avg,count)>having
-- having條件 若須引入聚合函數來對group by 結果進行過濾 則只能用having
-- like 模糊查詢 類似正則
-- 分析:先分組 select cno,avg(grade) from score group by cno
-- 第二步 having count(2)>=2
-- 第三步 and cno like '3%';
select cno,avg(grade),count(*) from score group by cno having count(cno)>=2 and cno like '3%';

注意:
1、where 后不能跟聚合函數,因為where執行順序大於聚合函數。
2、where 子句的作用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組之前過濾數據,條件中不能包含聚組函數,使用where條件顯示特定的行。
3、having 子句的作用是篩選滿足條件的組,即在分組之后過濾數據,條件中經常包含聚組函數,使用having 條件顯示特定的組,也可以使用多個分組標准進行分組。

-- 查詢分數大於70,小於90的sno列。
select sno grade from score where 70<grade<90;
select sno grade from score where grade between 70 and 90;
   
-- 查詢所有學生的sname,cno 和grade列
select sname,cno,grade from student as st,score as sc where st.sno=sc.sno;
mysql>  select sname,cno,grade from student as st,score as sc where st.sno=sc.sno;
      +--------+-------+-------+
      | sname | cno   | grade |
      +--------+-------+-------+
      | 王麗       | 3-105 |    92 |
      | 王麗       | 6-166 |    85 |
      | 王麗       | 9-888 |    86 |
      | 匡yi明     | 3-105 |    88 |
      | 匡yi明     | 6-166 |    79 |
      | 匡yi明     | 9-888 |    75 |
      | 陸君     | 3-105 |    76 |
      | 陸君     | 6-166 |    81 |
      | 陸君     | 9-888 |    68 |
      +--------+-------+-------+
       9 rows in set (0.00 sec)
       
-- 查詢所有學生的sno,cname和grade列 course cname score sno and grade
select sno,cname,grade from course as c,score as s where c.cno=s.cno;
mysql> select sno,cname,grade from course as c,score as s where c.cno=s.cno;
  +-----+------------+-------+
  | sno | cname     | grade |
  +-----+------------+-------+
  | 103 | 計算機導論           |    92 |
  | 103 | 數字電路         |    85 |
  | 103 | 高等數學         |    86 |
  | 105 | 計算機導論           |    88 |
  | 105 | 數字電路         |    79 |
  | 105 | 高等數學         |    75 |
  | 106 | 計算機導論           |    76 |
  | 106 | 數字電路         |    81 |
  | 106 | 高等數學         |    68 |
  +-----+------------+-------+
   9 rows in set (0.00 sec)

-- 查詢所有學生的sname,cname和grade列
-- sname--student cname--course grade--score
select sname,cname,grade from student as st,course as c,score as sc where c.cno=sc.cno and st.sno=sc.sno;
mysql> select sname,cname,grade from student as st,course as c,s
c.cno=sc.cno and st.sno=sc.sno;
  +--------+------------+-------+
  | sname | cname     | grade |
  +--------+------------+-------+
  | 王麗       | 計算機導論           |    92 |
  | 王麗       | 數字電路         |    85 |
  | 王麗       | 高等數學         |    86 |
  | 匡yi明     | 計算機導論           |    88 |
  | 匡yi明     | 數字電路         |    79 |
  | 匡yi明     | 高等數學         |    75 |
  | 陸君     | 計算機導論           |    76 |
  | 陸君     | 數字電路         |    81 |
  | 陸君     | 高等數學         |    68 |
  +--------+------------+-------+
   9 rows in set (0.00 sec)

-- 查詢95031班的學生每門課的平均分數 avg()平均分時
-- in 表示或的關系
-- cla-95031--student表 grade--score表 課程名稱 cname--course
select avg(grade),cno from score where sno in (select sno from student where cla='95031') group by cno;
select cla,avg(grade),cname from student as st,course as co,score as sc where st.sno=sc.sno and co.cno=sc.cno;

-- 查詢選修3-105課程的成績高於106號同學3-105成績的所有同學的記錄
select grade from score where sno='106' and cno='3-105';
select * from score where cno='3-105' and grade>(select grade from score where sno='106' and cno='3-105');
mysql> select * from score where cno='3-105' and grade>(select grade from score
where sno='106' and cno='3-105');
+-----+-------+-------+
| sno | cno   | grade |
+-----+-------+-------+
| 103 | 3-105 |    92 |
| 105 | 3-105 |    88 |
+-----+-------+-------+
2 rows in set (0.00 sec)

-- 查詢成績高於學號106課程為3-105的成績的所有記錄
select * from score where grade>(select grade from score where sno='106' and cno='3-105');

-- 查詢學號為108,101的同學同年出生的所有學生的sno,sname和sbirthday列。
-- 只要查年份 year(sbirthday)
select * from student where year(sbirthday) in (select year(sbirthday) from student where sno in (101,103));

-- 查詢張旭教師任課的學生成績。
select * from teacher where tname ='張旭';
select cno from course where tno=(select * from teacher where tname ='張旭');

-- 查詢選修某課程的同學人數多於3人的教師姓名
select cno from score group by cno having count(*)>2;
select tname from teacher where tno=(select tno from course where cno=(select cno from score group by cno having count(*)>3));

-- 查詢95033班和95031班的全體學生的記錄
select * from student where cla in ('95033','95031');

-- 查詢存在有85分以上成績的課程cno.
select cno from score where grade>85;

-- 查詢出計算機系教師所教課程的成績表。
select * from score where cno in (select cno from course where tno in (select tno from teacher where depart="計算機系"));

-- 查詢計算機系和電子工程系不同職稱的教師的tname和prof。
-- union 求並集
select prof from teacher where depart='電子工程系';
select * from teacher where depart='計算機系' and prof not in(select prof from teacher where depart='電子工程系')
union
select * from teacher where depart='電子工程系' and prof not in(select prof from teacher where depart='計算機系');

mysql> select * from teacher where depart='計算機系' and prof not in(select pro
from teacher where depart='電子工程系')
  ->  union
  ->  select * from teacher where depart='電子工程系' and prof not in(select
rof from teacher where depart='計算機系');
+-----+-------+------+---------------------+------+------------+
| tno | tname | tsex | tbirthday           | prof | depart     |
+-----+-------+------+---------------------+------+------------+
| 825 | 王萍     | 女   | 1972-05-05 00:00:00 | 助教     | 計算機系         |
| 856 | 張旭     | 男     | 1969-03-12 00:00:00 | 講師   | 電子工程系
|
+-----+-------+------+---------------------+------+------------+
2 rows in set (0.00 sec)

-- 查詢選修編號為3-105課程且成績至少高於選修編號為3-166的同學的cno,sno和grade,且成績從高到低次序排列。
-- any 大於其中至少一個
select * from score where cno='6-166';
select * from score where cno='3-105';
select * from score where cno='3-105' and grade>any(select grade from score where cno='6-166')
order by grade desc;

-- 查詢選修編號為3-105課程且成績至少高於選修編號為3-166的同學的cno,sno和grade
-- all 表示所有

select * from score where cno='6-166';
select * from score where cno='3-105';
select * from score where cno='3-105' and grade>all(select grade from score where cno='6-166');

-- 查詢所有教師和同學的name,sex和birthday.
select tname,tsex,tbirthday from teacher
union
select sname,ssex,sbirthday from student;

-- 查詢所有女教師和女同學的name,sex和birthday
select tname,tsex,tbirthday from teacher where tsex='女'
union
select sname,ssex,sbirthday from student where ssex='女';

-- 查詢成績比該課程平均成績低的同學的成績表。
-- 復制表score為表a和表b
select con,avg(grade) from score group by cno;
select * from score a where grade<(select avg(grade) from score b where a.cno = b.cno);
mysql>  select * from score a where grade<(select avg(grade) from score b where
a.cno = b.cno);
+-----+-------+-------+
| sno | cno   | grade |
+-----+-------+-------+
| 105 | 6-166 |    79 |
| 105 | 9-888 |    75 |
| 106 | 3-105 |    76 |
| 106 | 6-166 |    81 |
| 106 | 9-888 |    68 |
+-----+-------+-------+
5 rows in set (0.00 sec)

-- 查詢所有任課教師的tname和depart
select tname,depart from teacher where tno in (select tno from course);

-- 查詢至少有倆名男生的班號。
select cla from student where ssex='男' group by cla having count(*)>1;

-- 查詢student表中不性王的同學記錄。
select * from student;
select * from student where sname not like '王%';

-- 查詢student表中每個學生的姓名和年齡
-- year(now()) 查看當前年份
select sname,year(now())-year(sbirthday) from student;

-- 查詢student表中最大值和最小的birthday的日期值
select max(sbirthday) as '最大值',min(sbirthday) as '最小值' from student;
mysql> select max(sbirthday) as '最大值',min(sbirthday) as '最小值' from student
          ;
          +---------------------+---------------------+
          | 最大值                   | 最小值                 |
          +---------------------+---------------------+
          | 1977-09-01 00:00:00 | 1974-06-03 00:00:00 |
          +---------------------+---------------------+
           1 row in set (0.00 sec)
       
-- 以班號和年齡從大到小的順序查詢studente表中的全部記錄。
select * from student order by cla desc,sbirthday;

-- 查詢男教師及其所上的課程
select * from course where tno in (select tno from teacher where tsex='男');

-- 查詢最高分同學的sno,cno,和grade.
select * from score where grade=(select max(grade) from score);

-- 查詢和王麗同性別的所有同學的sname
select ssex from student where sname='王麗';
select sname from student where ssex=(select ssex from student where sname='王麗');

-- 查詢和王麗同性別並在同班的同學sname
select ssex from student where sname='王麗';
select sname from student where ssex=(select ssex from student where sname='王麗') and cla=(select cla from student where sname='王麗');

-- 查詢所有選修計算機導論課程的男同學的成績表。
select * from student where ssex='男';
   select * from course where cname='計算機導論';
   select * from score where cno=(select cno from course where cname='計算機導論') and sno in (select sno from student where ssex='男');
 
-- 假設用如下命令建立了一個grade表
create table gradeq(
low int(3),
  upp int(3),
  gradet char(1)
);
insert into gradeq values(90,100,'A');
insert into gradeq values(80,90,'B');
insert into gradeq values(70,80,'C');
insert into gradeq values(60,70,'D');
insert into gradeq values(50,60,'E');
 -- 先查詢所有學生的sno cno 和 gradet列
select sno,cno,gradet from score,gradeq where grade between low and upp;
mysql> select sno,cno,gradet from score,gradeq where grade between low and upp;
+-----+-------+--------+
| sno | cno   | gradet |
+-----+-------+--------+
| 101 | 3-105 | A     |
| 103 | 3-105 | A     |
| 103 | 6-166 | B     |
| 103 | 9-888 | B     |
| 105 | 3-105 | B     |
| 105 | 6-166 | C     |
| 105 | 9-888 | C     |
| 106 | 3-105 | C     |
| 106 | 6-166 | B     |
| 106 | 9-888 | D     |
+-----+-------+--------+
10 rows in set (0.00 sec)
sql 的四種連接查詢
-- 內連接 inner join 或者 join
-- 外連接
-- 左連接 left join 或者 left outer join
-- 有連接 right join 或者 right outer join
-- 完全外連接 full 或者 full outer join

創建倆個表
person表 id,name,cardId
create table person(
  id int,
      name varchar(20),
      cardId int
  );
   insert into person values(1,'張三',1);
   insert into person values(2,'李四',3);
   insert into person values(3,'王五',6);
   insert into person values(4,'馬六',9);

card表 id,name
   create table card(
  id int,
      name varchar(20)
  );
   
   insert into card values(1,'飯卡');
   insert into card values(2,'中國卡');
   insert into card values(3,'交通卡');
   insert into card values(4,'招商卡');
   insert into card values(5,'平安卡');
   
-- 並沒有創建外鍵
-- inner join 查詢(內連接) 或者可以使用join
-- 代碼解析:倆張表連接以后使得cardId=id使用inner join 來連接
-- join 左右是我們關聯的表 后跟on 后面的是條件
select * from person inner join card on person.cardId=card.id;
mysql> select * from person inner join card on person.cardId=card.id;
      +------+------+--------+------+--------+
      | id   | name | cardId | id   | name   |
      +------+------+--------+------+--------+
      |    1 | 張三     |      1 |    1 | 飯卡       |
      |    2 | 李四     |      3 |    3 | 交通卡     |
      +------+------+--------+------+--------+
       2 rows in set (0.00 sec)
       
-- left join 外連接(左連接)或者 left outer join
select * from person left join card on person.cardId=card.id;
mysql> select * from person left join card on person.cardId=card.id;
  +------+------+--------+------+--------+
  | id   | name | cardId | id   | name   |
  +------+------+--------+------+--------+
  |    1 | 張三     |      1 |    1 | 飯卡       |
  |    2 | 李四     |      3 |    3 | 交通卡     |
  |    3 | 王五     |      6 | NULL | NULL   |
  |    4 | 馬六     |      9 | NULL | NULL   |
  +------+------+--------+------+--------+
   4 rows in set (0.00 sec)
   -- 左外連接,會把左面的數據全都拿出來,而又變得數據條件相等的拿,不等的補NULL
   
-- right join 外連接(右鏈接) 或者 right outer join
select * from person right join card on person.cardId=card.id;
mysql>  select * from person right join card on person.cardId=card.id;
      +------+------+--------+------+--------+
      | id   | name | cardId | id   | name   |
      +------+------+--------+------+--------+
      |    1 | 張三     |      1 |    1 | 飯卡       |
      | NULL | NULL |   NULL |    2 | 中國卡     |
      |    2 | 李四     |      3 |    3 | 交通卡     |
      | NULL | NULL |   NULL |    4 | 招商卡     |
      | NULL | NULL |   NULL |    5 | 平安卡     |
      +------+------+--------+------+--------+
       5 rows in set (0.00 sec)
      -- 右外連接,會把右面的數據全都拿出來,而又變得數據條件相等的拿,不等的補NULL

-- full join 全外連接
----------- mysql 不支持 full join 外連接 ---------
select * from person full join card on person.cardId=card.id;
-- 所以mysql如果需要實現全外連接就需要用左連接union有鏈接即可
select * from person right join card on person.cardId=card.id
union
select * from person left join card on person.cardId=card.id;
mysql> select * from person right join card on person.cardId=card.id
  ->  union
  ->  select * from person left join card on person.cardId=card.id;
      +------+------+--------+------+--------+
      | id   | name | cardId | id   | name   |
      +------+------+--------+------+--------+
      |    1 | 張三     |      1 |    1 | 飯卡       |
      | NULL | NULL |   NULL |    2 | 中國卡     |
      |    2 | 李四     |      3 |    3 | 交通卡     |
      | NULL | NULL |   NULL |    4 | 招商卡     |
      | NULL | NULL |   NULL |    5 | 平安卡     |
      |    3 | 王五     |      6 | NULL | NULL   |
      |    4 | 馬六     |      9 | NULL | NULL   |
      +------+------+--------+------+--------+
       7 rows in set (0.00 sec)

 

數據庫的設計范式

  1. 要求:每一個分量必須是不可分的數據項。

    特點:

    1)有主鍵,且主鍵不能為空。

    2)字段不能再分。

     

    2.第二范式(2NF)

    要求:在范式一的基礎上,且每一個非主屬性完全函數依賴於主鍵。

    特點:

    1)滿足第一范式。

    2)表中的每一個非主屬性,必須完全依賴於本表主鍵。

    3)只有當一個表中,主鍵由兩個或以上的屬性組成的時候,才會出現不符合第二范式的情況。(如果出現不完全依賴那么只能發生在聯合主鍵的情況下。

3.第三范式(3NF)

要求:在第二范式的基礎上,且消除傳遞依賴性1)滿足第二范式

2)所有的非主鍵列依賴於主鍵列

注:3NF是對字段冗余性的約束,即任何字段不能由其他字段派生出來,它要求字段沒有冗余,但是沒有數據冗余的數據庫並不一定是最好的數據庫,所以有沒有冗余的設計,要綜合來考慮

 

-----mysql的查詢語句練習

 

學生表 student 學號 姓名  性別 出生年月日  所在班級
create table student(
  sno varchar(20) primary key,
      sname varchar(20) not null,
      ssex varchar(12) not null,
      sbirthday datetime,
      cla int(12)
  );
insert into student values("101","曾華","男","1977-09-01","95033");
insert into student values("102","匡明","男","1975-10-02","95031");
insert into student values("103","王麗","女","1976-01-23","95033");
insert into student values("105","匡yi明","男","1975-10-02","95031");
insert into student values("104","王er麗","女","1976-01-23","95033");
insert into student values("106","陸君","男","1974-06-03","95031");

--課程表 course 課程號 課程名稱 教師編號
表的約束--外鍵約束 foreign key reference
1 外鍵約束
一個表中某字段的值,受另一張表中某個字段的限制
主表(父表):提供數據的表
從表(子表):外鍵所在的表(引用主表中唯一性字段(主健,唯一)的值)
外鍵的值只能是主表中對應字段的值或者為null
foreign key references 主表(字段) --無名
constraint 約束名 foreign key references 主表(字段) -- 有名
foreign key references 主表(字段)  
constraint 約束名 foreign key references 主表(字段)
---------------------------------------
       create table course(
          cno varchar(20) primary key,
          cname varchar(20) not null,
          tno varchar(20) not null,
           foreign key(tno) references teacher(tno)

      );
       
insert into course values("3-105","計算機導論","825");
insert into course values("6-166","數字電路","856");
insert into course values("9-888","高等數學","831");
教師表 teacher 教師編號 教師名字 教師性別 出生年月日 職稱所在部門

create table teacher(
  tno varchar(20) primary key,
      tname varchar(20) not null,
      tsex varchar(10) not null,
      tbirthday datetime,
      prof varchar(20) not null,
      depart varchar(20) not null
  );
   insert into teacher values("804","李誠","男","1958-12-02","副教授","計算機系");
    insert into teacher values("856","張旭","男","1969-03-12","講師","電子工程系");
    insert into teacher values("825","王萍","女","1972-05-05","助教","計算機系");
    insert into teacher values("831","劉冰","女","1977-08-14","副教授","電子工程系");

– 成績表
– Score
– 學號
– 課程號
– 成績
-----------drop table score;
create table score(
sno varchar(20) not null,
  cno varchar(20) not null,
  grade decimal,
   foreign key(sno) references student(sno),
   foreign key(cno) references course(cno),
   primary key(sno,cno)
);
insert into score values("103","3-105","92");
insert into score values("103","6-166","85");
insert into score values("103","9-888","86");
insert into score values("105","3-105","88");
insert into score values("105","6-166","79");
insert into score values("105","9-888","75");
insert into score values("106","3-105","76");
insert into score values("106","6-166","81");
insert into score values("106","9-888","68");


 

sql 查詢語句
select * from student; 查詢student中的所有數據
select sname from student; 查詢student中的sname字段的值
select distinct depart from teacher; 查詢教師所有的單位既不重復的depart的值 -- distinct 去重
-- 查詢score表中的成績在60-80的所有記錄。
-- 查詢區間 between...and
select * from score where 60<grade<80;
select * from score where grade between 60 and 80;
-- 查詢 score 表中成績為85,86或88的紀錄。
-- 表示或者的關系查詢 in
select * from score where grade in(85,86,88);
mysql> select * from score where grade in(85,86,88);
      +-----+-------+-------+
      | sno | cno   | grade |
      +-----+-------+-------+
      | 103 | 6-166 |    85 |
      | 103 | 9-888 |    86 |
      | 105 | 3-105 |    88 |
      +-----+-------+-------+
       3 rows in set (0.00 sec)
       
-- 查詢student表中'96031'班或性別為女的同學紀錄
-- or表示或者
select * from student where class='95031' or ssex='女';
-- 以cla降序查詢student表中的所有記錄。
-- 升序order by asc 降序 order by desc
select * from student order by cla desc;
-- 以cno升序,degree降序查詢score 表中的所有記錄
select * from score order by cno asc,grade desc;
mysql> select * from score order by cno asc,grade desc;
      +-----+-------+-------+
      | sno | cno   | grade |
      +-----+-------+-------+
      | 103 | 3-105 |    92 |
      | 105 | 3-105 |    88 |
      | 106 | 3-105 |    76 |
      | 103 | 6-166 |    85 |
      | 106 | 6-166 |    81 |
      | 105 | 6-166 |    79 |
      | 103 | 9-888 |    86 |
      | 105 | 9-888 |    75 |
      | 106 | 9-888 |    68 |
      +-----+-------+-------+
       9 rows in set (0.00 sec)
-- 查詢'95031'班的學生人數。
-- 統計count
select count(*) from student where cla='95031';
      mysql> select count(*) from student where cla='95031';
          +----------+
          | count(*) |
          +----------+
          |        3 |
          +----------+
           1 row in set (0.00 sec)
   
-- 查詢score表中的最高分的學生學號和課程號。(子查詢或者排序)
-- 分析:找到最高分 select max(grade) from score;
-- 找到最高分的sno,cno
       select sno,cno from score where grade=(select max(grade) from score);
   -- 排序分析:limit 0,1 0表示開始索引,1表示取幾個
  -- select sno,cno,grade from score order by grade;
  -- select sno,cno,grade from score order by grade desc limit 0,1;
          mysql> select sno,cno from score where grade=(select max(grade) from score);
      +-----+-------+
      | sno | cno   |
      +-----+-------+
      | 103 | 3-105 |
      +-----+-------+
       1 row in set (0.00 sec)

-- 查詢每門課的平均成績
-- avg(grade)
  select avg(grade) from score where cno='9-888';
          mysql> select avg(grade) from score where cno='9-888';
          +------------+
          | avg(grade) |
          +------------+
          |    76.3333 |
          +------------+
           1 row in set (0.00 sec)
  -- 查詢每門課
  -- group by 分組
  select cno,avg(grade) from score group by cno;
mysql> select cno,avg(grade) from score group by cno;
      +-------+------------+
      | cno   | avg(grade) |
      +-------+------------+
      | 3-105 |    85.3333 |
      | 6-166 |    81.6667 |
      | 9-888 |    76.3333 |
      +-------+------------+
       3 rows in set (0.00 sec)
       
-- 查詢score表中至少有2名學生選修的並以3開頭的平均分數
-- where、聚合函數、having 在from后面的執行順序:
-- where>聚合函數(sum,min,max,avg,count)>having
-- having條件 若須引入聚合函數來對group by 結果進行過濾 則只能用having
-- like 模糊查詢 類似正則
-- 分析:先分組 select cno,avg(grade) from score group by cno
-- 第二步 having count(2)>=2
-- 第三步 and cno like '3%';
select cno,avg(grade),count(*) from score group by cno having count(cno)>=2 and cno like '3%';

注意:
1、where 后不能跟聚合函數,因為where執行順序大於聚合函數。
2、where 子句的作用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組之前過濾數據,條件中不能包含聚組函數,使用where條件顯示特定的行。
3、having 子句的作用是篩選滿足條件的組,即在分組之后過濾數據,條件中經常包含聚組函數,使用having 條件顯示特定的組,也可以使用多個分組標准進行分組。

-- 查詢分數大於70,小於90的sno列。
select sno grade from score where 70<grade<90;
select sno grade from score where grade between 70 and 90;
   
-- 查詢所有學生的sname,cno 和grade列
select sname,cno,grade from student as st,score as sc where st.sno=sc.sno;
mysql>  select sname,cno,grade from student as st,score as sc where st.sno=sc.sno;
      +--------+-------+-------+
      | sname | cno   | grade |
      +--------+-------+-------+
      | 王麗       | 3-105 |    92 |
      | 王麗       | 6-166 |    85 |
      | 王麗       | 9-888 |    86 |
      | 匡yi明     | 3-105 |    88 |
      | 匡yi明     | 6-166 |    79 |
      | 匡yi明     | 9-888 |    75 |
      | 陸君     | 3-105 |    76 |
      | 陸君     | 6-166 |    81 |
      | 陸君     | 9-888 |    68 |
      +--------+-------+-------+
       9 rows in set (0.00 sec)
       
-- 查詢所有學生的sno,cname和grade列 course cname score sno and grade
select sno,cname,grade from course as c,score as s where c.cno=s.cno;
mysql> select sno,cname,grade from course as c,score as s where c.cno=s.cno;
  +-----+------------+-------+
  | sno | cname     | grade |
  +-----+------------+-------+
  | 103 | 計算機導論           |    92 |
  | 103 | 數字電路         |    85 |
  | 103 | 高等數學         |    86 |
  | 105 | 計算機導論           |    88 |
  | 105 | 數字電路         |    79 |
  | 105 | 高等數學         |    75 |
  | 106 | 計算機導論           |    76 |
  | 106 | 數字電路         |    81 |
  | 106 | 高等數學         |    68 |
  +-----+------------+-------+
   9 rows in set (0.00 sec)

-- 查詢所有學生的sname,cname和grade列
-- sname--student cname--course grade--score
select sname,cname,grade from student as st,course as c,score as sc where c.cno=sc.cno and st.sno=sc.sno;
mysql> select sname,cname,grade from student as st,course as c,s
c.cno=sc.cno and st.sno=sc.sno;
  +--------+------------+-------+
  | sname | cname     | grade |
  +--------+------------+-------+
  | 王麗       | 計算機導論           |    92 |
  | 王麗       | 數字電路         |    85 |
  | 王麗       | 高等數學         |    86 |
  | 匡yi明     | 計算機導論           |    88 |
  | 匡yi明     | 數字電路         |    79 |
  | 匡yi明     | 高等數學         |    75 |
  | 陸君     | 計算機導論           |    76 |
  | 陸君     | 數字電路         |    81 |
  | 陸君     | 高等數學         |    68 |
  +--------+------------+-------+
   9 rows in set (0.00 sec)

-- 查詢95031班的學生每門課的平均分數 avg()平均分時
-- in 表示或的關系
-- cla-95031--student表 grade--score表 課程名稱 cname--course
select avg(grade),cno from score where sno in (select sno from student where cla='95031') group by cno;
select cla,avg(grade),cname from student as st,course as co,score as sc where st.sno=sc.sno and co.cno=sc.cno;

-- 查詢選修3-105課程的成績高於106號同學3-105成績的所有同學的記錄
select grade from score where sno='106' and cno='3-105';
select * from score where cno='3-105' and grade>(select grade from score where sno='106' and cno='3-105');
mysql> select * from score where cno='3-105' and grade>(select grade from score
where sno='106' and cno='3-105');
+-----+-------+-------+
| sno | cno   | grade |
+-----+-------+-------+
| 103 | 3-105 |    92 |
| 105 | 3-105 |    88 |
+-----+-------+-------+
2 rows in set (0.00 sec)

-- 查詢成績高於學號106課程為3-105的成績的所有記錄
select * from score where grade>(select grade from score where sno='106' and cno='3-105');

-- 查詢學號為108,101的同學同年出生的所有學生的sno,sname和sbirthday列。
-- 只要查年份 year(sbirthday)
select * from student where year(sbirthday) in (select year(sbirthday) from student where sno in (101,103));

-- 查詢張旭教師任課的學生成績。
select * from teacher where tname ='張旭';
select cno from course where tno=(select * from teacher where tname ='張旭');

-- 查詢選修某課程的同學人數多於3人的教師姓名
select cno from score group by cno having count(*)>2;
select tname from teacher where tno=(select tno from course where cno=(select cno from score group by cno having count(*)>3));

-- 查詢95033班和95031班的全體學生的記錄
select * from student where cla in ('95033','95031');

-- 查詢存在有85分以上成績的課程cno.
select cno from score where grade>85;

-- 查詢出計算機系教師所教課程的成績表。
select * from score where cno in (select cno from course where tno in (select tno from teacher where depart="計算機系"));

-- 查詢計算機系和電子工程系不同職稱的教師的tname和prof。
-- union 求並集
select prof from teacher where depart='電子工程系';
select * from teacher where depart='計算機系' and prof not in(select prof from teacher where depart='電子工程系')
union
select * from teacher where depart='電子工程系' and prof not in(select prof from teacher where depart='計算機系');

mysql> select * from teacher where depart='計算機系' and prof not in(select pro
from teacher where depart='電子工程系')
  ->  union
  ->  select * from teacher where depart='電子工程系' and prof not in(select
rof from teacher where depart='計算機系');
+-----+-------+------+---------------------+------+------------+
| tno | tname | tsex | tbirthday           | prof | depart     |
+-----+-------+------+---------------------+------+------------+
| 825 | 王萍     | 女   | 1972-05-05 00:00:00 | 助教     | 計算機系         |
| 856 | 張旭     | 男     | 1969-03-12 00:00:00 | 講師   | 電子工程系
|
+-----+-------+------+---------------------+------+------------+
2 rows in set (0.00 sec)

-- 查詢選修編號為3-105課程且成績至少高於選修編號為3-166的同學的cno,sno和grade,且成績從高到低次序排列。
-- any 大於其中至少一個
select * from score where cno='6-166';
select * from score where cno='3-105';
select * from score where cno='3-105' and grade>any(select grade from score where cno='6-166')
order by grade desc;

-- 查詢選修編號為3-105課程且成績至少高於選修編號為3-166的同學的cno,sno和grade
-- all 表示所有

select * from score where cno='6-166';
select * from score where cno='3-105';
select * from score where cno='3-105' and grade>all(select grade from score where cno='6-166');

-- 查詢所有教師和同學的name,sex和birthday.
select tname,tsex,tbirthday from teacher
union
select sname,ssex,sbirthday from student;

-- 查詢所有女教師和女同學的name,sex和birthday
select tname,tsex,tbirthday from teacher where tsex='女'
union
select sname,ssex,sbirthday from student where ssex='女';

-- 查詢成績比該課程平均成績低的同學的成績表。
-- 復制表score為表a和表b
select con,avg(grade) from score group by cno;
select * from score a where grade<(select avg(grade) from score b where a.cno = b.cno);
mysql>  select * from score a where grade<(select avg(grade) from score b where
a.cno = b.cno);
+-----+-------+-------+
| sno | cno   | grade |
+-----+-------+-------+
| 105 | 6-166 |    79 |
| 105 | 9-888 |    75 |
| 106 | 3-105 |    76 |
| 106 | 6-166 |    81 |
| 106 | 9-888 |    68 |
+-----+-------+-------+
5 rows in set (0.00 sec)

-- 查詢所有任課教師的tname和depart
select tname,depart from teacher where tno in (select tno from course);

-- 查詢至少有倆名男生的班號。
select cla from student where ssex='男' group by cla having count(*)>1;

-- 查詢student表中不性王的同學記錄。
select * from student;
select * from student where sname not like '王%';

-- 查詢student表中每個學生的姓名和年齡
-- year(now()) 查看當前年份
select sname,year(now())-year(sbirthday) from student;

-- 查詢student表中最大值和最小的birthday的日期值
select max(sbirthday) as '最大值',min(sbirthday) as '最小值' from student;
mysql> select max(sbirthday) as '最大值',min(sbirthday) as '最小值' from student
          ;
          +---------------------+---------------------+
          | 最大值                   | 最小值                 |
          +---------------------+---------------------+
          | 1977-09-01 00:00:00 | 1974-06-03 00:00:00 |
          +---------------------+---------------------+
           1 row in set (0.00 sec)
       
-- 以班號和年齡從大到小的順序查詢studente表中的全部記錄。
select * from student order by cla desc,sbirthday;

-- 查詢男教師及其所上的課程
select * from course where tno in (select tno from teacher where tsex='男');

-- 查詢最高分同學的sno,cno,和grade.
select * from score where grade=(select max(grade) from score);

-- 查詢和王麗同性別的所有同學的sname
select ssex from student where sname='王麗';
select sname from student where ssex=(select ssex from student where sname='王麗');

-- 查詢和王麗同性別並在同班的同學sname
select ssex from student where sname='王麗';
select sname from student where ssex=(select ssex from student where sname='王麗') and cla=(select cla from student where sname='王麗');

-- 查詢所有選修計算機導論課程的男同學的成績表。
select * from student where ssex='男';
   select * from course where cname='計算機導論';
   select * from score where cno=(select cno from course where cname='計算機導論') and sno in (select sno from student where ssex='男');
 
-- 假設用如下命令建立了一個grade表
create table gradeq(
low int(3),
  upp int(3),
  gradet char(1)
);
insert into gradeq values(90,100,'A');
insert into gradeq values(80,90,'B');
insert into gradeq values(70,80,'C');
insert into gradeq values(60,70,'D');
insert into gradeq values(50,60,'E');
 -- 先查詢所有學生的sno cno 和 gradet列
select sno,cno,gradet from score,gradeq where grade between low and upp;
mysql> select sno,cno,gradet from score,gradeq where grade between low and upp;
+-----+-------+--------+
| sno | cno   | gradet |
+-----+-------+--------+
| 101 | 3-105 | A     |
| 103 | 3-105 | A     |
| 103 | 6-166 | B     |
| 103 | 9-888 | B     |
| 105 | 3-105 | B     |
| 105 | 6-166 | C     |
| 105 | 9-888 | C     |
| 106 | 3-105 | C     |
| 106 | 6-166 | B     |
| 106 | 9-888 | D     |
+-----+-------+--------+
10 rows in set (0.00 sec)
sql 的四種連接查詢
-- 內連接 inner join 或者 join
-- 外連接
-- 左連接 left join 或者 left outer join
-- 有連接 right join 或者 right outer join
-- 完全外連接 full 或者 full outer join

創建倆個表
person表 id,name,cardId
create table person(
  id int,
      name varchar(20),
      cardId int
  );
   insert into person values(1,'張三',1);
   insert into person values(2,'李四',3);
   insert into person values(3,'王五',6);
   insert into person values(4,'馬六',9);

card表 id,name
   create table card(
  id int,
      name varchar(20)
  );
   
   insert into card values(1,'飯卡');
   insert into card values(2,'中國卡');
   insert into card values(3,'交通卡');
   insert into card values(4,'招商卡');
   insert into card values(5,'平安卡');
   
-- 並沒有創建外鍵
-- inner join 查詢(內連接) 或者可以使用join
-- 代碼解析:倆張表連接以后使得cardId=id使用inner join 來連接
-- join 左右是我們關聯的表 后跟on 后面的是條件
select * from person inner join card on person.cardId=card.id;
mysql> select * from person inner join card on person.cardId=card.id;
      +------+------+--------+------+--------+
      | id   | name | cardId | id   | name   |
      +------+------+--------+------+--------+
      |    1 | 張三     |      1 |    1 | 飯卡       |
      |    2 | 李四     |      3 |    3 | 交通卡     |
      +------+------+--------+------+--------+
       2 rows in set (0.00 sec)
       
-- left join 外連接(左連接)或者 left outer join
select * from person left join card on person.cardId=card.id;
mysql> select * from person left join card on person.cardId=card.id;
  +------+------+--------+------+--------+
  | id   | name | cardId | id   | name   |
  +------+------+--------+------+--------+
  |    1 | 張三     |      1 |    1 | 飯卡       |
  |    2 | 李四     |      3 |    3 | 交通卡     |
  |    3 | 王五     |      6 | NULL | NULL   |
  |    4 | 馬六     |      9 | NULL | NULL   |
  +------+------+--------+------+--------+
   4 rows in set (0.00 sec)
   -- 左外連接,會把左面的數據全都拿出來,而又變得數據條件相等的拿,不等的補NULL
   
-- right join 外連接(右鏈接) 或者 right outer join
select * from person right join card on person.cardId=card.id;
mysql>  select * from person right join card on person.cardId=card.id;
      +------+------+--------+------+--------+
      | id   | name | cardId | id   | name   |
      +------+------+--------+------+--------+
      |    1 | 張三     |      1 |    1 | 飯卡       |
      | NULL | NULL |   NULL |    2 | 中國卡     |
      |    2 | 李四     |      3 |    3 | 交通卡     |
      | NULL | NULL |   NULL |    4 | 招商卡     |
      | NULL | NULL |   NULL |    5 | 平安卡     |
      +------+------+--------+------+--------+
       5 rows in set (0.00 sec)
      -- 右外連接,會把右面的數據全都拿出來,而又變得數據條件相等的拿,不等的補NULL

-- full join 全外連接
----------- mysql 不支持 full join 外連接 ---------
select * from person full join card on person.cardId=card.id;
-- 所以mysql如果需要實現全外連接就需要用左連接union有鏈接即可
select * from person right join card on person.cardId=card.id
union
select * from person left join card on person.cardId=card.id;
mysql> select * from person right join card on person.cardId=card.id
  ->  union
  ->  select * from person left join card on person.cardId=card.id;
      +------+------+--------+------+--------+
      | id   | name | cardId | id   | name   |
      +------+------+--------+------+--------+
      |    1 | 張三     |      1 |    1 | 飯卡       |
      | NULL | NULL |   NULL |    2 | 中國卡     |
      |    2 | 李四     |      3 |    3 | 交通卡     |
      | NULL | NULL |   NULL |    4 | 招商卡     |
      | NULL | NULL |   NULL |    5 | 平安卡     |
      |    3 | 王五     |      6 | NULL | NULL   |
      |    4 | 馬六     |      9 | NULL | NULL   |
      +------+------+--------+------+--------+
       7 rows in set (0.00 sec)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM