zoukankan      html  css  js  c++  java
  • [数据库] SQL 语法之基础篇

    一、什么是 SQL ?

    SQL 是 Structured Query Language(结构化查询语言)的缩写,是一种专门用来与数据库沟通的语言。与其他语言(如英语或 C、C++、Java 这样的编程语言)不一样,SQL 中只有很少的词,这是有意而为的。设计 SQL 的目的是很好地完成一项任务 一 提供一种从数据库中读写数据的简单有效的方法。

    SQL 有如下的优点:

    • SQL 不是某个特定数据库供应商专有的语言。几乎所有重要的 DBMS 都支持 SQL ,所以学习此语言使你几乎能与所有数据库打交道;
    • SQL 简单易学。它的语句全都是由有很强描述性的英语单词组成,而且这些单词的数目不多;
    • SQL 虽然看上去很简单,但实际上是一种强有力的语言,灵活使用其语言元素,可以进行非常复杂和高级的数据库操作。

    二、创建、更新和删除表

    下面先讲讲授创建、更改和删除表的 SQL 语法。


    2.1 创建表

    用程序创建表,可以使用 SQL 的 CREATE TABLE 语句。下面的 SQL 语句创建本文中所用的 Products 表:

    CREATE TABLE Products( 
    prod id		CHAR(10)		NOT NULL,
    vend id     CHAR(10)        NOT NULL,        
    prod name   CHAR(254)       NOT NULL, 
    prod price  DECIMAL(8,2)    NOT NULL  DEFAULT 3,         
    proddesc    VARCHAR(1000)   NULL
    );
    

    从上面的例子可以看到,表名紧跟 CREATE TABLE 关键字。实际的表定义(所有列)括在圆括号之中,各列之间用逗号分隔。有一列的描述增加了 DEFAULT 3,指示 DBMS,如果不给出价格则使用价格 3。


    2.2 更新表

    更新表定义,可以使用 ALTER TABLE 语句。因为给已有表增加列可能是所有 DBMS 都支持的唯一操作,所以我们举个这样的例子:

    ALTER TABLE Vendors ADD vend_phone CHAR(20);   
    

    这条语句给 Vendors 表增加一个名为 vend_phone 的列,其数据类型为 CHAR。删除列,就使用DROP COLUMN col_name即可。


    2.3 删除表

    删除表(删除整个表而不是其内容)非常简单,如下所示:

    DROP TABLE CustCopy;
    

    这条语句删除 CustCopy 表。删除表没有确认,也不能撤销,执行这条语句将永久删除该表。

    使用关系规则防止意外删除 许多 DBMS 允许强制实施有关规则,防止删除与其他表相关联的表。在实施这些规则时,如果对某个表发布一条 DROP TABLE 语句,且该表是某个关系的组成部分,则 DBMS 将阻止这条语句执行,直到该关系被删除为止。

    三、插入数据

    下面介绍如何利用 SQL 的 INSERT 语句将数据插入表中。


    3.1 数据插入

    把数据插入表中的最简单方法是使用基本的 INSERT 语法,它要求指定表名和插入到新行中的值。下面举一个例子:

    INSERT INTO Customers VALUES('1000000006', 'Toy Land', '123 Any Street', 'New York', 'NY', '11111', 'USA', NULL, NULL);
    

    这个例子将一个新顾客插入到 Customers 表中。存储到表中每一列的数据在 VALUES 子句中给出,必须给每一列提供一个值。如果某列没有值,如上面的 cust_contact 和 cust_email 列,则应该使用 NULL 值(假定表允许对该列指定空值)。各列必须以它们在表定义中出现的次序填充。

    虽然这种语法很简单,但并不安全,应该尽量避免使用。上面的 SQL 语句高度依赖于表中列的定义次序,还依赖于其容易获得的次序信息。即使可以得到这种次序信息,也不能保证各列在下一次表结构变动后保持完全相同的次序。因此,编写依赖于特定列次序的 SQL 语句是很不安全的,这样做迟早会出问题。


    编写 INSERT 语句的更安全(不过更烦琐)的方法如下:

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

    这个例子与前一个 INSERT 语句的工作完全相同,但在表名后的括号里明确给出了列名。在插入行时,DBMS 将用 VALUES 列表中的相应值填入列表中的对应项。因为提供了列名,VALUES 必须以其指定的次序匹配指定的列名,不一定按各列出现在表中的实际次序。其优点是,即使表的结构改变,这条 INSERT 语句仍然能正确工作。


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

    要将一个表的内容复制到一个全新的表(运行中创建的表),可以使用 SELECT INTO 语句。MariaDB、MySQL、Oracle、PostgreSQL 和 SQLite 使用的语法如下:

    CREATE TABLE CustCopy AS SELECT * FROM Customers;
    

    这条 SELECT 语句创建一个名为 CustCopy 的新表,并把 Customers 表的整个内容复制到新表中。因为这里使用的是 SELECT *,所以将在 CustCopy 表中创建(并填充)与 Customers 表的每一列相同的列。要想只复制部分的列,可以明确给出列名,而不是使用 * 通配符。


    四、更新和删除数据

    下面介绍如何利用 UPDATE 和 DELETE 语句进一步操作表数据。


    4.1 更新数据

    更新(修改)表中的数据,可以使用 UPDATE 语句。例子如下:

    UPDATE Customers SET cust_contact = 'Sam Roberts', cust_email = 'sam@toyland.cxx' WHERE cust_id = '1000000006';
    

    UPDATE 语句以 WHERE 子句结束,它告诉 DBMS 更新哪一行。没有 WHERE 子句,DBMS 将会用这个电子邮件地址更新 Customers 表中的所有行,这不是我们希望的。


    4.2 删除数据

    从一个表中删除数据,使用 DELETE 语句。下面的语句从 Customers 表中删除一行:

    DELETE FROM Customers WHERE cust_id = '1000000006';
    

    这条语句很容易理解。DELETE FROM 要求指定从中删除数据的表名,WHERE 子句过滤要删除的行。在这个例子中,只删除顾客 1000000006。如果省略 WHERE 子句,它将删除表中每个顾客。


    五、检索数据

    下面介绍如何使用 SELECT 语句从表中检索一个或多个数据列。


    5.1 SELECT 语句

    正如上面所述,SQL语句是由简单的英语单词构成的。这些单词称为关键字,每个 SQL 语句都是由一个或多个关键字构成的。最经常使用的 SQL 语句大概就是 SELECT 语句了。它的用途是从一个或多个表中检索信息。

    关键字(keyword) 作为 SQL 组成部分的保留字。关键字不能用作表或列的名字。附录E列出了某些经常使用的保留字。

    为了使用 SELECT 检索表数据,必须至少给出两条信息一想选择什么,以及从什么地方选择。


    5.2 检索单个列

    我们将从简单的 SELECT 语句讲起,语句如下所示:

     SELECT prod_name FROM Products;
    

    上述语句利用 SELECT 语句从 Products 表中检索一个名为 prod_name 的列。所需的列名写在 SELECT 关键字之后,FROM 关键字指出从哪个表中检索数据。


    提示1: SQL 语句和大小写 请注意, SQL 语句不区分大小写,因此 SELECT 与 SELECT 是相同的。同样,写成 SELECT 也没有关系。许多 SQL 开发人员喜欢对 SQL 关键字使用大写,而对列名和表名使用小写,这样做使代码更易于阅读和调试。不过,一定要认识到虽然 SQL 是不区分大小写的,但是表名、列名和值可能有所不同(这有赖于具体的DBMS及其如何配置)。

    提示2:使用空格 在处理 SQL 语句时,其中所有空格都被忽略。 SQL 语句可以写成长长的一行,也可以分写在多行。多数 SQL 开发人员认为,将 SQL 语句分成多行更容易阅读和调试。

    5.3 检索多个行

    要想从一个表中检索多个列,仍然使用相同的 SELECT 语句。唯一的不同是必须在 SELECT 关键字后给出多个列名,列名之间必须以逗号分隔。

     SELECT  prod_id, prod_name, prod_price FROM Products;
    

    这条语句使用 SELECT 语句从表 Products 中选择多个数据。在这个例子中,指定了 3 个列名,列名之间用逗号分隔。


    5.4 检索所有列

    除了指定所需的列外(如上所述,一个或多个列),SELECT 语句还可以检索所有的列而不必逐个列出它们。在实际列名的位置使用星号(*)通配符可以做到这点,如下所示:

     SELECT  * FROM Products;
    

    如果给定一个通配符(*),则返回表中所有列。列的顺序一般是列在表定义中出现的物理顺序,但并不总是如此。


    5.5 检索不同的值

    如前所述,SELECT 语句返回所有匹配的行。但是,如果你不希望每个值每次都出现,该怎么办呢?办法就是使用 DISTINCT 关键字,顾名思义,它指示数据库只返回不同的值。

     SELECT  DISTINCT vend_id FROM Products;
    

    SELECT DISTINCT vend_id 告诉 DBMS 只返回不同(具有唯一性)的 vend_id 行。如果使用 DISTINCT 关键字,它必须直接放在列名的前面。

    警告:不能部分使用 DISTINCT DISTINCT 关键字作用于所有的列,不仅仅是跟在其后的那一列。例如,你指定 SELECT DISTINCT vend_id,prod_price,除非指定的两列完全相同,否则所有的行都会被检索出来。

    5.6 限制结果

    SELECT 语句返回指定表中所有匹配的行,很可能是每一行。如果你只想返回第一行或者一定数量的行,该怎么办呢?这是可行的,然而遗憾的是,各种数据库中的 SQL 实现并不相同。

    如果你使用 My SQL 、MariaDB、Postgre SQL 或者 SQL ite,需要使用 LIMIT子句,像这样:

     SELECT  prod_name FROM Products LIMIT 5;
    

    上述代码使用 SELECT 语句来检索单独的一列数据。LIMIT 5 指示 My SQL 等 DBMS 返回不超过 5 行的数据。


    为了得到后面的 5 行数据,需要指定从哪儿开始以及检索的行数,像这样:

     SELECT  prod_name FROM Products LIMIT 5 OFFSET 5;
    

    LIMIT 5 OFFSET 5 指示 My SQL 等 DBMS 返回从第 5 行起的 5 行数据。第一个数字是指从哪儿开始,第二个数字是检索的行数。

    警告:第 0 行 第一个被检索的行是第 0 行,而不是第 1 行。因此,LIMIT 1 OFFSET 1 会检索第 2 行,而不是第 1 行。

    提示:My SQL 和MariaDB快捷键 My SQL 和MariaDB支持简化版的LIMIT 4 OFFSET 3语句,即LIMIT 3,4。使用这个语法,之前的值对应 LIMIT,之后的值对应 OFFSET。

    5.7 使用注释

    我们先来看行内注释:

     SELECT  prod_name FROM Products;    --这是一条注释
    

    注释使用--(两个连字符)嵌在行内,之后的文本就是注释。


    你也可以进行多行注释,注释可以在脚本的任何位置停止和开始。

    /*  SELECT  prod_name, vend_id 
    FROM Products; */
    
    SELECT  prod_name FROM Products;
    

    注释从/*开始,到*/结束,之间的任何内容都是注释。


    六、排序检索数据

    下面讲授如何使用 SELECT 语句的 ORDER BY 子句,根据需要排序检索出的数据。


    6.1 排序数据

    为了明确地排序用 SELECT 语句检索出的数据,可使用 ORDER BY 子句。ORDER BY 子句取一个或多个列的名字,据此对输出进行排序。请看下面的例子:

    SELECT prod_name FROM Products ORDER BY prod_name;
    
    

    ORDER BY 子句,指示 DBMS 软件对 prod_name 列以字母顺序排序数据。

    注意:ORDER BY 子句的位置 在指定一条 ORDER BY 子句时,应该保证它是 SELECT 语句中最后一条子句。如果它不是最后的子句,将会出现错误消息。

    6.2 按多个列排序

    下面的代码检索 3 个列,并按其中两个列对结果进行排序 一 首先按价格,然后按名称排序。

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

    对于上述例子中的输出,仅在多个行具有相同的 prod_price 值时才对产品按 prod_name 进行排序。如果 prod_price 列中所有的值都是唯一的,则不会按 prod_name 排序。(先对 prod_price 排序,再对 prod_name 排序)


    6.3 按列位置排序

    除了能用列名指出排序顺序外,ORDER BY 还支持按相对列位置进行排序。为理解这一内容,我们来看个例子:

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

    SELECT 清单中指定的是选择列的相对位置而不是列名。ORDER BY 2 表示按 SELECT 清单中的第二个列 prod_name 进行排序。ORDER BY 2, 3 表示先按 prod_price,再按 prod_name 进行排序。


    6.4 指定排序方向

    数据排序不限于升序排序(从 A 到 Z),这只是默认的排序顺序。还可以使用 ORDER BY 子句进行降序(从 Z 到 A )排序。为了进行降序排序,必须 指定 DESC 关键字。例子如下:

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

    DESC 关键字只应用到直接位于其前面的列名。在上例中,只对 prod_price 列指定 DESC,对 prod_name 列不指定。因此,prod_price 列以降序排序,而 prod_name 列(在每个价格内)仍然按标准的升序排序。

    警告:在多个列上降序排序 如果想在多个列上进行降序排序,必须对每一列指定 DESC 关键字。

    七、过滤数据

    下面将讲授如何使用 SELECT 语句的 WHERE 子句指定搜索条件。


    7.1 使用 WHERE 子句

    在 SELECT 语句中,数据根据 WHERE 子句中指定的搜索条件进行过滤。WHERE 子句在表名(FROM 子句)之后给出,如下所示:

    SELECT prod_name, prod_price FROM Products WHERE prod_price = 3.49;
    
    

    这条语句从 products 表中检索两个列,但不返回所有行,只返回 prod_price 值为 3.49 的行。


    7.2 WHERE 子句操作符

    SQL 支持下表列出的所有条件操作符。

    操作符 说明
    = 等于
    != 不等于
    < 小于
    <= 小于等于
    > 大于
    >= 大于等于
    BETWEEN 在指定的两个值之间
    IS NULL 为NULL值

    1. 范围内检查

    要检查某个范围的值,可以使用 BETWEEN 操作符。其语法与其他 WHERE 子句的操作符稍有不同,因为它需要两个值,即范围的开始值和结束值。下面的例子说明如何使用 BETWEEN 操作符,它检索价格在 5 美元和 10 美元之间的所有产品:

    SELECT prod_name, prod_price FROM Products WHERE prod_price BETWEEN 5 AND 10;
    
    

    从这个例子可以看到,在使用 BETWEEN 时,必须指定两个值——所需范围的低端值和高端值。这两个值必须用 AND 关键字分隔。


    2. 空值检查

    确定值是否为 NULL,不能简单地检查是否 =NULL。SELECT 语句有一个特殊的 WHERE 子句,可用来检查具有 NULL 值的列。这个 WHERE 子句就是 IS NULL 子句。其语法如下:

    SELECT prod_name FROM Products WHERE prod_price IS NULL;
    
    

    这条语句返回所有没有价格(空 prod_price 字段,不是价格为 0)的产品。


    八、高级数据过滤

    下面讲授如何组合 WHERE 子句以建立功能更强、更高级的搜索条件。我们还将学习如何使用 NOT 和 IN 操作符。


    8.1 组合 WHERE 子句

    第 4 课介绍的所有 WHERE 子句在过滤数据时使用的都是单一的条件。为了进行更强的过滤控制,SQL 允许给出多个 WHERE 子句。这些子句有两种使用方式,即以 AND 子句或 OR 子句的方式使用。


    1. AND 操作符

    要通过不止一个列进行过滤,可以使用 AND 操作符给 WHERE 子句附加条件。下面的代码给出了一个例子:

    SELECT prod_id, prod_price, prod_name FROM Products WHERE vend_id = 'DLL01' AND prod_price <= 4;
    
    

    此 SQL 语句检索由供应商 DLL01 制造且价格小于等于 4 美元的所有产品的名称和价格。


    2. OR 操作符

    OR 操作符与 AND 操作符正好相反,它指示 DBMS 检索匹配任一条件的行。事实上,许多 DBMS 在 OR WHERE 子句的第一个条件得到满足的情况下, 就不再计算第二个条件了。例子如下:

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

    此 SQL 语句检索由任一个指定供应商制造的所有产品的产品名和价格。


    8.2 IN操作符

    IN 操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN 取一组由逗号分隔、括在圆括号中的合法值。下面的例子说明了这个操作符:

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

    此 SELECT 语句检索由供应商 DLL01 和 BRS01 制造的所有产品。IN 操作符后跟由逗号分隔的合法值,这些值必须括在圆括号中。 你可能会猜测 IN 操作符完成了与 OR 相同的功能,恭喜你猜对了!


    8.3 NOT操作符

    WHERE 子句中的 NOT 操作符有且只有一个功能,那就是否定其后所跟的任何条件。NOT 关键字可以用在要过滤的列前,而不仅是在其后。下面的例子说明了这个操作符:

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

    这里的 NOT 否定跟在其后的条件,因此,DBMS 不是匹配 vend_id 为 DLL01,而是匹配非 DLL01 之外的所有东西。


    九、用通配符进行过滤

    下面介绍什么是通配符、如何使用通配符以及怎样使用 LIKE 操作符进行通配搜索,以便对数据进行复杂过滤。


    1. 百分号(%)通配符

    最常使用的通配符是百分号(%)。在搜索串中,% 表示任何字符出现任意次数。例如,为了找出所有以词 Fish 起头的产品,可发布以下 SELECT 语句:

    SELECT prod_id, prod_name FROM Products WHERE prod_name LIKE 'Fish%';
    
    

    此例子使用了搜索模式 'Fish%’。在执行这条子句时,将检索任意以 Fish 起头的词。% 告诉 DBMS 接受 Fish 之后的任意字符,不管它有多少字符。


    2. 下划线(_)通配符

    另一个有用的通配符是下划线(_)。下划线的用途与 % —样,但它只匹配单个字符,而不是多个字符。例子如下:

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

    这个 WHERE 子句中的搜索模式给出了后面跟有文本的两个通配符。


    3. 方括号([])通配符

    方括号([])通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符。例如,找出所有名字以 J 或 M 起头的联系人,可进行如下查询:

    SELECT cust_contact FROM Customers WHERE cust_contact LIKE '[JM]%';
    

    这一搜索模式使用了两个不同的通配符。[JM] 匹配任何以方括号中字母开头的联系人名,它也只能匹配单个字符。[JM] 之后的 % 通配符匹配第一个字符之后的任意数目的字符,返回所需结果。


    参考:

    《SQL 必知必会》


  • 相关阅读:
    c++中ctype常用函数总结(isprint isblank..)
    c++的const总结(转)
    c++重载输入输出运算符
    c++中的友元重载
    c++函数模板二栈实现
    c++函数模板1
    c++中IO输入输出流总结<二>
    c++中IO输入输出流总结<一>
    四层与七层得区别(转)
    ORACLE操作
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/11594760.html
Copyright © 2011-2022 走看看