SQL必知必会笔记

SQL必知必会笔记

第一课 了解SQL

  • 主键列中的值不允许修改或更新
  • 主键值不能重用(如果某行从表中删除,他的主键不能赋给以后的新行)

第二课 检索数据

SQL语句不区分大小写,一般对SQL关键字使用大写,而对列名和表名使用小写。

select语句

  SELECT prod_name FROM Products;

DISTINCT

使用DISTINCT关键字返回不同的值,DISTINCT关键字必须直接放在列名的前面。

  SELECT DISTINCT vend_id
  FROM Products;

限制结果

  1. TOP(SQL Server)
    使用TOP关键字来限制返回多少行

     SELECT TOP prod_name
     RROM Products;
    
  2. ROWNUM(Oracle) 使用ROWNUM关键字来计算行

     SELECT prod_name
     FROM Products
     WHERE ROWNUM <=5;
    
  3. LIMIT(MySQL) 使用LIMIT关键字来限制返回多少行

     # 返回前5条
     SELECT prod_name
     FROM Products
     LIMIT 5;
    
     # 指定从那条开始
     SELECT prod_name
     FROM Products
     LIMIT 5 OFFSET 5;  -- 返回5-9行,数据从第0行开始。
    

注释

    /* 这是一段
    注释*/
    # 这是一条注释
    SELECT prod_name -- 这也是一条注释
    FROM Products;

第三课 排序检索数据

排序数据

使用ORDER BY来对输出进行排序。

  SELECT prod_name
  FROM Products
  ORDER BY prod_name;

注意:ORDER BY必须是SELECT语句中最后一条子句,如果不是最后的子句,会出现错误消息。

按多个列排序

  SELECT prod_id,prod_price,prod_name
  FROM Products
  ORDER BY prod_price,prod_name;

指定排序方向

使用DESC关键字进行降序排序。

  SELECT prod_id,prod_price,prod_name
  FROM Products
  ORDER BY prod_price DESC,prod_name; -- 按price降序,name升序

DESC只应用到直接位于其前面的列名,如果想在多个列上进行降序排序,必须对每一列指定DESC关键字。
大多数数据库管理系统中默认A和a的字典序中是相同的,当时允许管理员改变这种行为。

第四课 过滤数据

WHERE子句操作符

操作符 说明
= 等于
<> 不等于
!= 不等于
< 小于
<= 小于等于
!< 不小于
> 大于
>= 大于等于
!> 不大于
BETWEEN 在指定的两个值之间
IS NULL 为NULL值
IS NOT NULL 不为NULL
  SELECT prod_name,prod_price
  FROM Products
  WHERE prod_price BETWEEN 5 AND 10;

检查字段是否为空值,不能用=NULL,而要用IS NULL

  SELECT prod_name,prod_price
  FROM Products
  WHERE prod_price IS NULL;

第五课 高级数据过滤

AND,OR 操作符

AND的优先级高于OR,AND和OR进行组合时推荐使用圆括号进行明确分组。

IN操作符

  SELECT prod_name,prod_price
  FROM Products
  WHERE vend_id IN ('DLL01','BRS01');

IN操作符完成了OR相同的功能,但执行更快。

NOT操作符

WHEREz子句中用来否定其后条件的关键字。 NOT可以用在要过滤的列前,不仅仅是在其后。

  SELECT prod_name,prod_price
  FROM Products
  WHERE NOT vend_id = 'DLL01';

第六课 用通配符进行过滤

LIKE操作符

  • % 通配符
    百分号表示0个,1个或多个任意字符。但WHERE name LIKE ‘%’不会匹配值为NULL的行。

    SELECT prod_id,prod_name
    FROM Products
    WHERE prod_name LIKE 'Fish%';
    
  • _ 通配符 下划线只匹配单个字符

    SELECT prod_id,prod_name
    FROM Products
    WHERE prod_name LIKE '_ inch teddy bear';
    

第七课 创建计算字段

字段拼接

使用加号+或两个竖杆||,视DBMS而定

  SELECT vend_name + '(' + vend_country + ')'
  FROM Vendors
  ORDER BY vend_name;

TRIM函数

使用RTRIM()去掉字符串右边的空格,使用LTRIM()去掉左边的空格,使用TRIM()去掉两边的空格

  SELECT vend_name + '(' + TRIM(vend_country) + ')'
  FROM Vendors
  ORDER BY vend_name;

使用别名

别名使用AS关键字

  SELECT vend_name + '(' + TRIM(vend_country) + ')'
         AS vend_title
  FROM Vendors
  ORDER BY vend_name;

算数计算

支持加减乘除运算符

  SELECT prod_id
         quantity
         quantity*item_price AS expanded_price
  FROM OrderItems
  WHERE order_num = 20008;

第八课 使用数据处理函数

UPPER()函数

Upper()函数将文本转换为大写

  SELECT vend_name,UPPER(vend_name) AS vend_name_upcase
  FROM Vendors
  ORDER BY vend_name;

常用文本处理函数

函数 说明
left() 返回字符串左边的字符
LENGTH() 返回字符串长度
LOWER() 将字符串转换为小写
LTRIM() 去掉字符串左边的空格
RIGHT() 返回字符串右边的字符
RTRIM() 去掉字符串右边的空格
SOUNDEX() 返回字符串的SOUNDEX值
UPPER() 将字符串转换为大写

第九课 汇总数据

SQL聚集函数

函数 说明
AVG() 平均值
COUNT() 行数
MAX() 最大值
MIN() 最小值
SUM() 值之和

如果指定列名,则COUNT()函数会忽略指定列的值为空的行,但COUNT(* )不会忽略空行。

  SELECT COUNT(* ) AS num_cust
  FROM Customers;

  SELECT COUNT(cust_email) AS num_cust
  FROM Customers;

DISTINCT

对于所有执行计算,默认ALL参数,如果要包含不同的值,指定DISTINCT参数。

  SELECT AVG(DISTINCT prod_price) AS avg_price
  FROM Products
  WHERE vend_id = 'DLL01';

第十课 分组数据

GROUP BY

GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。

  SELECT vend_id,COUNT(#) AS num_prods
  FROM Products
  GROUP BY vend_id;

HAVING

WHERE在数据分组之前进行过滤,HAVING在数据分组后进行过滤。WHERE排除的行不包括在分组中。

  SELECT vend_id,COUNT(* ) AS num_prods
  FROM Products
  WHERE prod_price >= 4
  GROUP BY vend_id
  HAVING COUNT(* ) >= 2;

一般在使用GROUP BY子句时,应该也给出ORDER BY子句,这是保证数据正确排序的唯一方法。

第十一课 使用子查询

子查询即嵌套查询

  SELECT cust_id
  FROM Orders
  WHERE order_num IN (SELECT order_num
                      FROM OrderItems
                      WHERE prod_id = 'GRAN01');



  SELECT cust_name,
         cust_state,
         (SELECT COUNT(* )
          FROM Orders
          WHERE Orders.cust_id = Customers.cust_id) AS orders
  FROM Customers
  ORDER BY cust_name;

第十二课 联结表

创建联结

  SELECT vend_name,prod_name,prod_price
  FROM Vendors,Products
  WHERE Vendors.vend_id = Products.vend_id;

创建高级联结

表别名

Oracle不支持AS关键字,直接指定表名即可。(因此,应该是Customers C,而不是Customers AS C)。

自联结

查询所有与Jim Jones同一公司的所有顾客

  #方法一:子查询
  SELECT cust_id,cust_name,cust_contact
  FROM Customers
  WHERE cust_name = (SELECT cust_name
                    FROM Customers
                    WHERE cust_contact = 'Jim Jones');

  #方法二:联结
  SELECT c1.cust_id,c1.cust_name,c1.cust_contact
  FROM Customers AS c1, 大专栏  SQL必知必会笔记Customers AS c2
  WHERE c1.cust_name = c2.cust_name
  AND c2.cust_contact = 'Jim Jones';

许多DBMS处理联结远比处理子查询快。

自然联结

外联结

联结包含了那些在相关表中没有关联的行,这种联结称为外联结。 外联接可以是左向外联接、右向外联接或完整外部联接。
在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:
1)LEFT JOIN或LEFT OUTER JOIN
左向外联接的结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。
2)RIGHT JOIN 或 RIGHT OUTER JOIN
右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
3)FULL JOIN 或 FULL OUTER JOIN
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。

  #内联结
  select a.* ,b.* from a inner join b on a.id=b.parent_id
  #左联结,a在左b在右,若b中没有a中对应行,显示为空,所有的a都会出现
  select a.* ,b.* from a left join b on a.id=b.parent_id
  #右联结,a在左b在右,若a中没有b中对应行,显示为空,所有的b都会出现
  select a.* ,b.* from a right join b on a.id=b.parent_id
  #完全联结
  select a.* ,b.* from a full join b on a.id=b.parent_id

第十四课 组合查询

UNION

  SELECT cust_name,cust_contact,cust_email
  FROM Customers
  WHERE cust_state IN ('IL','IN','MI')
  UNION
  SELECT cust_name,cust_contact,cust_email
  FROM Customers
  WHERE cust_name = 'Fun4ALL';

  #功能相同
  SELECT cust_name,cust_contact,cust_email
  FROM Customers
  WHERE cust_state IN ('IL','IN','MI')
  OR cust_name = 'Fun4ALL';

UNION规则

  • UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分割。
  • UNION中的每个查询必须包含相同的列、表达式或聚集函数
  • 列数据类型必须兼容

    使用UNION ALL返回所有匹配行

    使用UNION时,重复的行会被自动取消。如果想返回所有的匹配行,可使用UNION ALL。

    UNION结果排序

    在用UNION组合查询时,只能使用一条ORDER BY子句,而且必须位于最后一条SELECT语句后。

第十五课 插入数据

插入完整的行

有两种方式,指定列名或使用默认列顺序。推荐使用指定列名

  INSERT INTO Customers(cust_id,
                        cust_contact,
                        cust_email,
                        cust_name,
                        cust_address,
                        cust_city,
                        cust_state,
                        cust_zip)
  VALUES('1000006',
          NULL,
          NULL,
          'Toy',
          '123 Any',
          'New York',
          'NY',
          '11111');

不管使用哪种INSERT语法,VALUES的数目必须正确。如果不提供列名,则必须给每个表列提供一个值;如果提供列名,则必须给列出的每个列一个值。否则,就会产生一条错误消息,相应的行不能成功插入。

插入部分行

省略的列必须满足一下条件:

  1. 该列定义为允许NULL值
  2. 在表定义中给出默认值。这表示如果不给出值,将使用默认值。

插入检索出的数据

    INSERT INTO Customers(cust_id,
                          cust_contact,
                          cust_email,
                          cust_name,
                          cust_address,
                          cust_city,
                          cust_state,
                          cust_zip)
    SELECT cust_id,
           cust_contact,
           cust_email,
           cust_name,
           cust_address,
           cust_city,
           cust_state,
           cust_zip
    FROM CustNew; INSERT SELECT 中SELECT语句可以包含WHERE子句,以过滤插入的数据。

###从一个表复制到另一个表

  SELECT *
  INTO CustCopy
  FROM Customers;

更新和删除数据

更新数据

  UPDATE Customers
  SET cust_email = 'KIN@store.com',
      cust_contact = 'Sam'
  WHERE cust_id = '10000005';

删除某列的值,可以设置它为NULL

  UPDATE Customers
  SET cust_email = NULL
  WHERE cust_id = '1000005';

删除数据

  • 从表中删除特定行

    DELETE FROM Customers
    WHERE cust_id = '10000006';
    
  • 删除所有行
    不要使用DELETE,可以使用TRUNCATE TABLE,速度更快。

创建和操纵表

创建表

如果不指定是否为可以为空,则默认可以为NULL,只有不允许NULL值的列可以作为主键。

    CREATE TABLE OrderItems
    (
      order_id       INTEGER        NOT NULL     primary key, --第一种主键创建方式
      order_num      INTEGER        NOT NULL,
      order_item     INTEGER        NOT NULL,
      pro_id         CHAR(10)       NOT NULL,
      quantity       INTEGER        NOT NULL      DEFAULT 1,
      order_state    CHAR(50)       NULL,
      order_zip      CHAR(10)         ,
      --第二种主键创建方式:在这里写入primary key (order_id,order_num)
    ) ### 更新表

  ALTER TABLE Vendors
  ADD vend_phone CHAR(20);

  ALTER TABLE Vendors
  DROP COLUMN vend_phone;

删除表

  DROP TABLE CustCopy;

重命名表

不同DBMS语法不同

第十八课 使用视图

为什么使用视图

  1. 重用SQL语句
  2. 简化复杂的SQL操作
  3. 使用表的一部分而不是全部
  4. 保护数据,授予用户部分表的部分权限而不是全部
  5. 更改数据格式和表示。

创建视图

使用CREATE VIEW来创建视图。

  CREATE VIEW ProductsCustomers AS
  SELECT cust_name,cust_contact,pro_id
  FROM Customers,Orders,OrderItems
  WHERE Customers.cust_id = Orders.cust_id
  AND OrderItems.order_num = Orders.order_num;

利用视图简化复杂的联结

  SELECT cust_name,cust_contact
  FROM ProductsCustomers
  WHERE pro_id = 'RGAN01';

利用视图来重新格式化检索出的数据

  CREATE VIEW VendorLocations AS
  SELECT RTRIM(vend_name) + '(' + RTRIM(vend_country) + ')'
        AS vend_title
  FROM Vendors;

  SELECT *
  FROM VendorLocations;

过滤不想要的字段

使用视图计算字段

第十九课 使用存储过程

简单来说,存储过程就是为以后使用而保存的一条或多条SQL语句。

执行存储过程

使用EXCUTE关键字。

  EXECUTE AddNewProduct('JTS01',
                        'Stuffed Eiffel Tower',
                        6.49,
                        'introduce of product'); ### 创建存储过程 不同DBMS不同语法,一下是Oracle版本

  CREATE PROCEDURE MailingListCount(
    ListCount OUT INTEGER
  )
  IS
  v_rows INTEGER;
  BEGIN
      SELECT COUNT(* ) INTO v_rows
      FROM Customers
      WHERE NOT cust_email IS NULL;
      ListCount := v_rows;
  ENDS;

第二十课 管理事务处理

提交事务

  BEGIN TRANSACTION
  DELETE OrderItems WHERE order_num = 12345
  DELETE Orders WHERE order_num = 12345
  COMMIT TRANSACTION

使用保留点

  SAVE TRANSACTION delete1;
  ROLLBACK TRANSACTION delete1;

第二十一课 使用游标

游标可以实现在检索出来的行中前进或退后

创建游标

  DECLARE CustCursor CURSOR
  FOR
  SELECT * FROM Customers
  WHERE cust_email IS NULL

使用游标

使用OPEN CURSOR 语句打开游标。
使用FETCH语句访问游标数据。
使用CLOSE语句关闭游标。

第二十二课 高级SQL特性

主键

  1. 任意两行的主键都不相同
  2. 每行都具有一个主键
  3. 包含主键值的列不允许修改和更新
  4. 主键值不能重用

    #创建表时指定主键
    CREATE TABLE Vendors ( vend_id CHAR(50) NOT NULL PRIMARY KEY, vend_name CHAR(30) NULL );

    #使用CONSTRAINT语法来指定主键 ALTER TABLE Vendors ADD CONSTRAINT PRIMARY KEY (vend_id);

    外键

    CREATE TABLE Orders ( cust_id CHAR(10) NOT NULL REFERENCES Customers(cust_id) ); #或者 ALTER TABLE Orders ADD CONSTRAINT FOREIGN KEY (cust_id) REFERENCES Customers (cust_id)

检查约束

使用CHECK语句来检查约束

  CREATE TABLE OrderItems
  (
    ...
    quantity INTEGER NOT NULL CHECK(quantity>0)
  );
  #或者
  ADD CONSTRAINT CHECK (gender LIKE '[MF]');

索引

  CREATE INDEX prod_name_ind
  ON PRODUCTS (prod_name);

触发器

关键字TRIGGER,不同DBMS语法不同

上一篇:工具类第一弹、Rabbitmq监听器


下一篇:MySQL必知必会(四)阅读笔记