传知_2_mysql

来源:互联网 发布:unity3d 3dsmax 编辑:程序博客网 时间:2024/06/05 11:34

 

 

 

数据库:

查看当前数据库

show  databases;

 

创建数据库

create database abc;

 

删除数据库

drop database abc;

 

进入某个数据库——要操作某个数据库内的东西,一定要先进入该数据库。

use 数据库名;

 

查看某个数据库内所有表

show tables;

 

数据表 是数据库内存放数据的基本单元。

          就类似于现实中一个表格,

          在这个表格中,每行代表一条记录。

                        每列代表一个Field

查看某个表的结构:

   —— 可以看到该表包含哪些数据列,每个数据列的数据类型。

desc 表名

 

查看某个表里数据:

select * from 表名;

 

现实生活中的表格、包括Excel表格,它们都是给人看的。

而数据库的表,通常都是通过程序来访问的。

 

但对于数据库的数据表,通常会通过程序来读写,因此呢,

 

使用SQLStructured Query Language)结构化查询语言来操作数据库。

 

SQL分类:

DDL 数据定义语言,它主要负责增、删、改数据库对象。

                  它主要createdropalter关键字组成。

DCL 数据控制语言,GRANT INVOKE 收回权限。

 

查询语句 select

DML 数据操作语言,它主要由INSERTupdateDELETE关键字组成。

                  它主要负责增、删、改数据。

事务控制语句: commitrollback savepoint组成。

 

 

====DDL====

create/drop/alter

主要用于对数据库对象进行增、删、修改操作。

——这三个关键字往往还要与其他关键字结合使用,用于操作指定类型的数据库对象。

 

对表的操作:

1. 建表

create table 表名

(

       #多个列定义 , 多个列定义之间用逗号隔开

       列名 类型 default 默认值。

)  [W1] 

 

 

2. 删除表

drop table 表名

 

3. 修改表

   a 增加列  alter table 表名

               add 列定义

 

      alter table news_inf

      add post_time datetime;

 

      -- 默认增加的列,用于在最后。

      #将新增的列放在指定位置。

      alter table news_inf

      add post_ip varchar(255) after news_content;

 

      #将新增的列放在最前面

      alter table news_inf

      add new_news_id varchar(255) first;

 

   b 删除列

       alter table 表名

               drop 列名

      alter table news_inf

      drop new_news_id;

 

   c。修改列:

      alter table 表名

      modify 已有列名 新的列定义

 

      alter table news_inf

      modify post_time date default '2001-12-12';

 

      如果要改列名,用change

      alter table 表名

      change 已有列名 新列名 新的列定义

 

 

      alter table news_inf

      change post_time post_date date default '2001-12-12';

 

 

对表的操作:

 

建表:create table 表名。创建了一个表结构,表里面依然没有数据。

删除表:drop table 表名。

修改表:alter table 表名 modify|change|add|drop

 

truncate 表名      [W2] 

截断操作——对于大部分数据库来说,它是DDL

因为MySQL早先它甚至只是toy数据库,所以MySQLtruncate实现并不好。

 

按标准,Truncate应该是一个DDL,它总是“截断”表中的全部数据,

         因此它的速度比delete语句(删除数据)的速度要快得多。

 

---约束(constraint---

它用于对数据库中数据的完整性进行约束:

约束分为5类:

-非空

-唯一

-主键

-外键

check

 

===非空约束===

指定某个数据列不允许为null

 

非空约束,总是列级约束,总是对单列起作用。

可以在建表时指定。也可以通过修改表来增加或删除。

 

非空约束:not null

 

create table category_inf

(

 category_id int,

 category_name varchar(255) not null,

 category_desc varchar(255)

);

 

#修改表时增加非空约束

alter table news_inf

modify news_title varchar(255) not null;

 

#修改表时删除非空约束

alter table news_inf

modify news_title varchar(255) null;

 

当你向表中插入数据、或修改数据时,

如果你的数据与约束冲突,数据无法插入、数据也无法修改。

 

===唯一约束===

指定某个数据列或列组合的值不允许重复。

唯一约束既可用列级约束语法,也可用表级约束语法。

它既可对单列起作用,也可对多列组合起作用。

 

唯一约束:unique

 

create table item_inf

(

 item_id int,

 item_barcode varchar(255) unique,

 item_name varchar(255),

 item_price decimal

);

 

insert into item_inf

values(1 , '123a' , '键盘' , 12);

insert into item_inf

values(2 , '123a' , '鼠标' , 15);

 

列级约束:指的是建表时直接把约束紧跟在列定义之后。

表级约束:指的是建表时使用单独的约束定义来定义约束。

          [constraint 约束名] 约束关键(列或列组合)

 

create table cat_inf

(

 cat_id int,

 cat_name varchar(255),

 cat_age int, nique unique(cat_name)

);

 

 

# 列组合不能重复!

# 对于列组合不能重复的情况,只能用表级约束语法。

create table sys_users

(

 user_id int,

 user_name varchar(255),

 user_pass varchar(255),

 unique(user_name , user_pass)

);

1  a   b

2  a   c

3  d   b

 constraint cat_name_u

 

#两列都不能重复。

create table sys_users

(

 user_id int,

 user_name varchar(255) unique,

 user_pass varchar(255) unique

);

1  a   b

2  a   c

3  d   b

 

修改表时增加唯一约束:

alter table 表名

add 约束定义。

 

alter table user_inf

add constraint user_name_unique unique(user_name[X3] );

 

删除唯一约束

alter table 表名

drop index 约束名    [W4] 

 

alter table user_inf

drop index user_name_unique;

 

insert into user_inf

values

(1, 'a' , 'b' , '123' , 'ss' , 'xx' , now() , 23);

 

insert into user_inf

values

(1, 'a' , 'c' , '123' , 'ss' , 'xx' , now() , 23);

 

!!!!!!!!!当你想对数据表进行修改时,而且表中已有数据情况下,对表的修改很容易失败!

如果你要做的修改与表中数据冲突,那么修改就会失败了!

 

----主键约束---- primary key

每条记录时,总会有一列或列组合,系统找到这列或这些列组合的值,

就可以根据该值来唯一地、确定一条记录。

主键默认的有唯一、非null

 

在一个数据表中,只要确定了主键值,就可以唯一地找到对应的记录。

一个表中,最多只能有一个主键。但主键可由多个列的列组合来确定。

 

对于现代的数据库建模理论,通常建议:

不要采用具有实际物理意义的列作为主键,

应该额外地为数据表增加一列,这列没有实际意义,只是一个逻辑编号,

通常建议采用这列作为主键。

 

通常建议让系统为这列来分配值,而不是让程序员指定!

MySQLSQL Server为这种逻辑主键列提供了identity支持。

auto_increment 有两个要求:

1. 这列必须是主键。

2. 这列的数据类型必须是整型。

 

create table item_inf

(

 item_id int primary key auto_increment,

 item_barcode varchar(255) unique,

 item_name varchar(255),

 item_price decimal

);

 

insert into item_inf

values(null , 'a1230' , '鼠标' , '12'),

(null , 'a2345' , '键盘' , '15');

 

主键也可以用表级约束语法来建,

尤其是当你要为多列的组合建约束时,更只能用表级约束语法。

 

create table sys_users

(

 user_name varchar(255),

 user_pass varchar(255),

 constraint aa primary key(user_name , user_pass)

);

 

删除主键

alter table 表名

drop primary key;

 

alter table sys_users

drop primary key;

 

数据字典——看上去也像表,但通常是视图,数据字典通常只能查看。

            数据字典里记录了数据库中所有的数据库对象的信息。

 

MySQL来说,使用information_schema保存数据字典信息。

SQL Server来说,使用master数据保存数据字典信息。

 

----外键---- foreign key

现实世界中,实体与实体之间存在如下关联关系:

11

1N

NN

 

一个人 -- 多匹马

典型的 1 N关联关系。

 

create table wrangler_inf

(

 wrangler_id int primary key auto_increment,

 wrangler_name varchar(255)

);

 

create table horse_inf

(

 horse_id int primary key auto_increment,

 horse_name varchar(255),

 horse_weight double

);

 

insert into wrangler_inf

values

(null , '张三'),

(null , '李四'),

(null , '王五');

 

insert into horse_inf

values

(null , '张新' , 200.0),

(null , '追风' , 210.0),

(null , '宝马' , 120),

(null , '骐骥' , 145);

 

外键列的值就是为了让系统知道,这条记录和哪条记录有关联关系。

 

1 N

1是主,保存主记录的那个表称主表! 父表。

N是从,保存从记录的那个表称从表! 子表。

这就是典型的主从关系。

 

总是在从表上增加外键列。

 

drop table horse_inf;

 

create table horse_inf

(

 horse_id int primary key auto_increment,

 horse_name varchar(255),

 horse_weight double,

 wrangler_id int,

 foreign key(wrangler_id) references wrangler_inf(wrangler_id)

);

 

insert into horse_inf

values

(null , '张新' , 200.0  , 1),

(null , '追风' , 210.0 , 1),

(null , '宝马' , 120 , 2),

(null , '骐骥' , 145 , 2);

 

外键列的值必须是主表里被参照列中已有的值。

insert into horse_inf

values

(null , '月牙' , 200.0  , 5);

 

 

删除外键约束:

alter table 表名

drop foreign key 外键约束名

 

自关联:参照自身主键,主表和从表是同一个。

 

create table emp_inf

(

 emp_id int primary key auto_increment,

 emp_name varchar(255),

 emp_age int,

 #记录自己的经理

 manager_id int,

 foreign key(manager_id) references emp_inf(emp_id)

);

 

insert into emp_inf

values

(null , '张三' , 25 , null),

(null , '李四' , 23 , 1),

(null , '王五' , 22 , 1);

 

 

多重关联:

商品表

用户表

商品可以属于某个人(卖家)

商品可以被谁购买(买家)

 

create table shop_users

(

 user_id int auto_increment primary key,

 user_name varchar(255)

);

 

create table goods_table

(

 goods_id int auto_increment primary key,

 goods_name varchar(255),

 seller_id int,

 buyer_id int,

 # 记录卖家信息

 foreign key(seller_id) references shop_users(user_id),

 # 记录买家信息

 foreign key(buyer_id) references shop_users(user_id)

);

 

insert into shop_users

values(null , 'aa'),

(null , 'bb'),

(null , 'cc');

 

insert into goods_table

values

(null , '键盘' , 2 , 1);

 

 

---约束---   外键约束代码.txt

对数据增加一些限制条件,用于保证数据库里数据完整性。

5类约束:

 

not null   列级约束、只能对单列起作用。

unique     列级约束,也可以是表级约束。既可要求单列的值不允许重复,也可要求多列组合的值不允许重复。

primary key 每个数据表都应该有PK,而且我们建议没有物理的逻辑主键。

            这个逻辑主键应该让系统自动编号,为主键列提供identity支持。auto_increment

foreign key 为了记录两个表里记录之间的关联关系。

            1N 主从表。

 

现实世界上,实体与实体之间存在

11 :两个表的关系是平等,因此可以在任何一方增加外键。

       一旦增加外键,那么增加外键的一方就是从表。

 

boygirl之间存在11的关联:

所以可以在任何一方增加外键,在那边增加外键,那么它就是从表

 

create table girl_inf

(

 girl_id int primary key auto_increment,

 girl_name varchar(255),

 girl_weight double

);

create table boy_inf

(

 boy_id int primary key auto_increment,

 boy_name varchar(255),

 girlfriend int unique,

 foreign key(girlfriend) references girl_inf(girl_id)

);

■■■■可以在任意一方增加外键列,而且外键列上定义unique约束■■■■

 

insert into girl_inf

values

(null, '凤姐' , 60);

insert into boy_inf

values

(null , '张三' , 1),

(null , '李四' , 1);

 

1N

 

NN 两个表的关系也是平等。

     NN的关联关系要使用连接表来记录

两个表都是主表,连接表是从表。

customerseller之间存在NN的关联:

create table customer_inf

(

 customer_id int primary key auto_increment,

 customer_name varchar(255),

 customer_address varchar(255)

);

create table seller_inf

(

 seller_id int primary key auto_increment,

 seller_name varchar(255),

 seller_dept varchar(255)

);

#使用连接表来记录两个实体之间的关联关系

create table customer_seller

(

 customer_id int,

 seller_id int,

 foreign key(customer_id) references customer_inf(customer_id),

 foreign key(seller_id) references seller_inf(seller_id)

);

insert into customer_inf

values

(null , '孙泰声' , '小新塘'),

(null , '王五' , '石牌村');

insert into seller_inf

values

(null , '小赵' , '电器部'),

(null , '小王' , '蔬菜部');

 

insert into customer_seller

values

(1 , 1),

(1 , 2),

(2 , 1);

 

check约束:check约束就是一个boolean表达式。

           只有当check约束的boolean表达式返回true时,这条记录才能被插入或者被修改。

 

create table aged_inf

(

 aged_id int primary key auto_increment,

 aged_name varchar(255),

 aged_age int,

 check(aged_age > 60 and aged_age < 110)

);

 

insert into aged_inf

values

(null , '张三' , 23);

 

----索引----

index 目录。

索引:记录一条记录的关键内容,以及它对应的位置。

  位置分为2类:一种是逻辑位置:

               还有一种是物理位置:这种索引在Oracle中叫聚簇索引。

索引的好处:加快查询。

      坏处:增加数据存储空间。增加、修改、删除记录时,需要较大的开销来维护索引。

 

建立索引:

自动:建PKFKunique都会自动建索引。

手动:由程序员来建立索引。

      create index 索引名

      on 表名();

 

删除索引:

 

自动:删除表时,索引被删除。

手动:drop index 索引名 on 指定表。

 

create index name_index

on aged_inf(aged_name);

 

drop index name_index on aged_inf;

 

----------DML语句---------

DDL是对数据库中的对象(表、约束、视图、索引等)进行增、删、修改等操作。

DML对数据表中数据(数据行)进行增、删、修改等操作。

insert 插入

delete 删除

update 修改

 

■■■■

insert into 表名

values(一行记录);

 

一般来说,每条insert语句只能插入一条记录。

 

# 插入一条记录时,不想为每列都指定值。

insert into 表名(1 , 2 , 3)

values (val1 , val2 , val3);

 

insert into aged_inf(aged_name)

values ('关羽');

 

可以将选择出来的记录插入进入

insert into 表名[(1 , 2 , 3)]

select 子句

 

■■■■delete

delete from 表名

where logic_expression

----logic_expression的值为true,对应的记录行被删除。

 

delete from aged_inf

where aged_id > 5;

如果没有where子句,相当于where子句总是返回true

 

■■■■update

update 表名

set 1=val1 , 2=val2, 3=val3 ...

where logic_expression

----logic_expression的值为true,对应的记录行被修改

 

update aged_inf

set aged_name = '猪八戒'

where aged_id%2 = 0;

 

--------select语句--------

 

select 列名 | 表达式 | 变量 | 常量

from 表名 | 视图 | 子查询

where logic_expression

 

----logic_expression的值为true,对应的记录行被选择出来。

    where确定要选择哪些行。

    select 确定选择哪些列。

 

select *

from

 

select aged_id , aged_name

from aged_inf

where aged_id > 3;

 

select 12

from aged_inf;

 

select语句的执行过程:

 

for(row : table)

{

   if(where子句中logic_expression)

   {

       输出 select子句的列表

   }

}

 

select 12 * aged_id test

from aged_inf;

 

select 12 * aged_id , test

from aged_inf;

 

select 12 * aged_id , 'test'

from aged_inf;

 

select 12 * aged_id 'test'

from aged_inf;

 

select 12 * aged_id , "test"

from aged_inf;

 

select 12 * aged_id , 234

from aged_inf;

 

select 12 * aged_id '234'

from aged_inf;

 

select aged_name , length(aged_name)

from aged_inf;

 

#mysql中直接计算某个表达式的值:

select 5;

select now();

 

SQL语句中函数:

 

不同的数据库,单行函数大同小异,虽然函数的名称可能各有差异,

但这些函数实现的功能最后是差不多的。

 

单行函数:

   字符串函数 LENGTH

   日期/时间函数 nowdayofmonth

   数学函数 ceilfloorABSroundrand

   转换函数: 负责完成类型转换。

 

 

mysql> SELECT 1+'1';

        -> 2

mysql> SELECT CONCAT(2,' test');

        -> '2 test'

 

 

mysql> SELECT 38.8, CAST(38.8 AS CHAR);

        -> 38.8, '38.8'

mysql> SELECT 38.8, CONCAT(38.8);

        -> 38.8, '38.8'

 

SELECT PI()+0.000000000000000000;

 

SELECT ROUND(1.298, 1);

SELECT FLOOR(7 + (RAND() * 5));

 

SELECT TRUNCATE(1.223,1);

 

 

 

 

流程控制函数:

IF(logic_expresss, val1 , val2) logic_exprtrue,返回val1 ,否则返回val2

CASE Case operator

IFNULL(val1 , val2)  如果val1null,返回val2;否则返回val1

NULLIF(val1 , val2)  如果val1 = val2 返回null ,否则返回val1

 

aged_name进行处理,当aged_name的长度小于4时,直接输出。

aged_name的长达大于4时,只保留前2位,并添加...

select if(length(aged_name) <= 4 , aged_name , concat(substr(aged_name , 1 , 2) , '...')) '人名'

from aged_inf;

 

CASE value WHEN [compare_value1] THEN result1 [WHEN [compare_value2] THEN result2 ...] [ELSE resultN] END

 

CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END

 

select aged_age , case when aged_age<30 then '年轻人'

                       when aged_age>30 and aged_age<48 then '中年人'

                       when aged_age>48 then '老年人'

                  end '分类'

from aged_inf;

 

 

#update记录

update boy_inf

set boy_age=48

where boy_name='农夫山泉';

 

update boy_inf

set boy_age=18

where boy_name='下雨天';

 

update boy_inf

set boy_age=25

where boy_name='character';

 

update boy_inf

set boy_age=36

where boy_name='越野车一句句科技';

 

 

 

#select语句

 

#if判断语句

select if(LENGTH(boy_name)<5,boy_name,CONCAT(lEFT(boy_name,3),'...')) Name

,CHAR_LENGTH(boy_name) Length,

if(isnull(girlfriend),'还需寻觅','革命成功') 革命

from boy_inf;

 

select boy_name,if(isnull(girlfriend),'还需寻觅','革命成功')

from boy_inf;

 

 

#case判断语句

select

if(LENGTH(boy_name)<5,boy_name,CONCAT(lEFT(boy_name,3),'...')) Name,

CHAR_LENGTH(boy_name) Length,

if(isnull(girlfriend),'还需寻觅','革命成功') 革命,

case

when boy_age<20 then '未成年'

when boy_age>20 and boy_age<30 then '青年人'

when boy_age>30 then '已过期'

end '分类'

from boy_inf;

 

 

 

 

 

SQL语句

DML insert update delete

DDL create table/index/database

    drop

    alter

select语句

 

JDBC编程。

允许使用JAVA程序来操作数据库。

需要使用Java程序开发更友好的GUI界面,让用户来操作。

 

 

 

SQL语法:

DML

DDL

DCL

事务控制语句

select

 

select 列名|表达式|变量|常量

from 数据源(表|视图|子查询)

where logic_expre

 

for (row : 数据源)

{

    if( logic_expre)

    {

       选出 select子句后的列表

    }

}

 

多表连接查询:

在很多时候,我们要查询的数据并不是来自于一个表,

可能需要来自多个数据表。

 

这时候就需要进行多表查询!

 

多表查询的语法:

SQL92标准:就我个人认为SQL92语法简洁,但可读性略差。

SQL99标准:可读性更好。

 

SQL 92的多表查询语句:

 

select 列名|表达式|变量|常量

from 1 , 2 ...

where 连接条件

      and 数据筛选条件

 

多表查询时,很容易出现一个问题:多个表之间存在同名的列。

为了区分数据列到底来自于哪个表,可以在列前增加表名、表别名作为前缀。

 

===等值连接===

select h.* , w.wrangler_name

from horse_inf h , wrangler_inf w

where h.wrangler_id = w.wrangler_id;

 

===不等值连接===

select h.* , w.wrangler_name

from horse_inf h , wrangler_inf w

where h.wrangler_id > w.wrangler_id;

 

查询的表有几个,这里的循环就嵌套几次。

for(row1 : table1)

{

    for(row2 : table2)

    {

        ...

        //查询的表有几个,这里的循环就嵌套几次。

        if( logic_expre)

        {

            选出 select子句后的列表

        }

    }

}

select h.* , w.wrangler_name

from horse_inf h , wrangler_inf w

where h.wrangler_id < w.wrangler_id;

 

select h.* , w.wrangler_name

from horse_inf h , wrangler_inf w

where h.wrangler_id <= w.wrangler_id;

 

 

select h.* , w.wrangler_name

from horse_inf h , wrangler_inf w

where h.wrangler_id != w.wrangler_id;

 

===外联接===

 

MySQL根本不支持SQL92的外联接

 

如果我们要求某个表中的记录,即使它没有配对的记录,

我们也想将其选出。

 

select h.* , w.wrangler_name

from horse_inf h , wrangler_inf w

where h.wrangler_id = w.wrangler_id(+);

——强制把horse_inf表中不匹配的记录选出。

SQL92的多表语法规则是:

那边增加外能行,对方表中的记录全部被选出!

select h.* , w.wrangler_name

from horse_inf h , wrangler_inf w

where h.wrangler_id(+) = w.wrangler_id;

——强制把wrangler_inf表中不匹配的记录选出。

 

select h.* , w.wrangler_name

from horse_inf h , wrangler_inf w;

 

SQL 99 的多表查询语句:

 

select 列名|表达式|变量|常量

from 1

xxx join 2

[on 指定连接条件]

xxx join 3

[on 指定连接条件]

...

xxx join N

[on 指定连接条件]

 

where 数据筛选条件

 

SQL92相比:

SQL99中的连接条件不再放到where子句中,而是用on子句来指定。

 

1. 自然连接

natural join

 

select h.* , w.wrangler_name

from horse_inf h

natural join wrangler_inf w;

 

natural join有一个隐含的连接条件:

它的连接条件是基于两个表中同名的列来进行连接。

 

2. 交叉连接

cross join

它其实和SQL92中不指定连接条件的效果一样。

 

select h.* , w.wrangler_name

from horse_inf h

cross join wrangler_inf w;

 

3. 普通内连接

[inner join] on来指定连接连接

select h.* , w.wrangler_name

from horse_inf h

inner join wrangler_inf w

on h.wrangler_id = w.wrangler_id;

 

select h.* , w.wrangler_name

from horse_inf h

inner join wrangler_inf w

on h.wrangler_id > w.wrangler_id;

 

select h.* , w.wrangler_name

from horse_inf h

inner join wrangler_inf w

on h.wrangler_id < w.wrangler_id;

 

4. 联接

left|right|full [outer] join

left join 就是左边表的记录全部被选出。

right join 是右边表的记录全部被选出。

full join 两边的表的记录全部被选出。

 

select h.* , w.wrangler_name

from horse_inf h

left join wrangler_inf w

on h.wrangler_id = w.wrangler_id;

 

select h.* , w.wrangler_name

from horse_inf h

right join wrangler_inf w

on h.wrangler_id = w.wrangler_id;

 

====MySQL并不支持全外联接====

select h.* , w.wrangler_name

from horse_inf h

full join wrangler_inf w

on h.wrangler_id = w.wrangler_id;

 

子查询

指在查询语句中嵌套另一个查询。

子查询可以出现在两个位置:

1. from之后  子查询本质上就是一个数据源。也叫所谓行内视图,相当于一个临时的视图

2. where子句中。

 

视图:视图本质上就是一个有名字的查询语句。

 

create view 视图名

as

select语句

==== 所谓视图,无非就是给select语句起个名字而已。

 

create view horse_view

as

select h.* , w.wrangler_name

from horse_inf h

left join wrangler_inf w

on h.wrangler_id = w.wrangler_id;

 

对视图进行查询时,与普通表没有区别。

但通常不要对视图执行DML操作!!!!——因为视图本身只是一个select语句,它自身并不存储数据。

视图的优势:

1. 通过把select语句定义成视图,可以简化查询。

2. 通过视图,可以为同一份数据提供多个逻辑视图,从而能更好地保护数据。

 

select * from horse_view where horse_id<2;

[W5] 

===子查询作为数据源===

select s.* from (select h.* , w.wrangler_name

from horse_inf h

left join wrangler_inf w

on h.wrangler_id = w.wrangler_id) s where horse_id<2;

 

===子查询作为筛选条件===

 

select * from horse_view

where horse_id > 2;

 

==单行、单列子查询,子查询的结果相当于一个标量值==

select * from horse_view

where horse_id > (select aged_id

from aged_inf

where aged_name = '猪八戒');

 

==多行、单列子查询==

此时子查询相当于返回一个List,因此需要使用多行运算符。

 

select * from horse_view

where horse_id in (select aged_id

from aged_inf);

 

select * from horse_view

where horse_id >any (select aged_id

from aged_inf);

 

select * from horse_view

where horse_id >all (select aged_id

from aged_inf);

 

select * from horse_view

where horse_id <all (select aged_id

from aged_inf);

 

select * from horse_view

where horse_id <any (select aged_id

from aged_inf);

 

==多行、多列子查询==

子查询相当于返回一个List,每个List元素相当于一个数组。

或者要求一个数组和另一个数组相当。

 

select * from horse_view

where (horse_id , horse_id) in (select horse_id , wrangler_id

 from horse_inf);

 

====分组和组函数====

SQL语句中可以使用函数:

单行函数:每行输入,将会产生一行输出。以数据库配套的文档为准,就像你们查API文档一样。

多行函数:聚集函数。多行输入,会产生一行的统计结果。

         count  统计记录条数count(*) ,

               select count(aged_name) from aged_inf;

           去除重复记录,可以在select后紧跟distinct

           统计时去除重复: select count(distinct aged_name)from aged_inf;

         sum 

               计算总和:select sum(aged_age) from aged_inf;

               计算总和重复记录只统计一条:select sum(distinct aged_age) from aged_inf;            

         max

               select max(aged_age) from aged_inf;

         min

               select min(aged_age) from aged_inf;

         avg

               计算平均值:select avg(aged_age) from aged_inf;

               计算平均值重复记录只统计一条:select avg(distinct aged_age) from aged_inf;   

 

默认情况下,分组函数将表中的所有记录当成一组,整个的最终只生成一条记录。

为了显式进行分组,可以考虑使用group by子句,         

 

group by的作用是:将指定列,或指定列列表中值相同的记录当成一组进行计算。

 

select avg(emp_age) , emp_depart from  emp_inf

group by emp_depart;

having对组进行过滤:

 

select avg(emp_age) , emp_depart from  emp_inf

group by emp_depart

having avg(emp_age) > 30;

 

having子句和where子句有点像

 

select avg(emp_age) , emp_depart from  emp_inf

group by emp_depart

having emp_depart like '%';

 

select avg(emp_age) , emp_depart from  emp_inf

where emp_depart like '%'

group by emp_depart;

 

应该优先考虑使用where子句进行数据筛选!

SQL优化的规范:数据筛选尽早完成!

 

如果having子句中出现了组函数,那么where子句就无能为力了!

因为where子句中不能出现组函数!。

 

 

SQL里有2通配符

% 可以代表任意多个字符。

_ 可以代表一个任意的字符。


建立表时,mysql check在语法上是支持的,但功能上是不支持的,

mysql对其操作比较特殊,如果使用非InnoDB数据引擎,truncat delete要快,

如果使用InnoDB,在mysql5.03之前,两个完全一样,但5.03之后,truncat delete要快,但

如果此表被外键约束参照,truncat又变为delete操作

如果在建立表时已经用,就不用加add了,如果在建立表后增加的约束,就要用add

如果没有指定 唯一 约束的名字

其默认名字就是 列名

删除时可以直接指定其列名

drop index ...

视图

使用子查询要注意的

1 子查询要用括号

2 当子查询当成是数据表时(出现在from后),可以为此子查询起别名,尤其是要作为前缀来限定数据列时,必须给子查询起别名

3 当子查询 当过滤条件时,将子查询放在比较运算符右边,这样可以增强查询查询的可读性

4 当子查询 当过滤条件时,单行子查询要用单行运算符,多行子查询要用多行运算符