【数据库】SQL Server基础语法

本文详细介绍了SQL的基本查询语句,包括SELECT、ORDER BY、WHERE、JOIN、UNION等,以及如何进行数据过滤、排序、分组、聚合等操作。此外,还涵盖了事务处理、存储过程和游标的使用,以及表和视图的创建与操纵。内容全面,适用于数据库管理和开发人员学习参考。
摘要由CSDN通过智能技术生成

文章目录

检索数据(SELECT FROM)

检索单个列

SELECT column_name FROM table_name;

注意: 检索返回的条目的顺序是随机的,下同。

检索多个列

SELECT column_name1, column_name2 FROM table_name;

检索所有列

SELECT * FROM table_name;

嵌套查询

SELECT cust_id
FROM Oredrs
WHERE order_num IN (SELECT order_num
					FROM OrderItems
					WHERE prod_id = 'RGAN01');
SELECT cust_name,
cust_state,
(SELECT COUNT(*)
		FROM Orders
		WHERE Orders.cust_id = Customers.cust_id) AS
orders
FROM Customers
ORDER BY cust_name;

排序检索数据(ORDER BY)

按单个列排序

SELECT column_name 
FROM table_name
ORDER BY column_name;

注意: 可以指定SELECT外的表中的其他属性作为排序的列,下同。

按多个列排序

SELECT column_name1,  column_name2,  column_name3
FROM table_name
ORDER BY column_name1, column_name2, column_name3;

当指定多个列排序时,应严格按顺序执行。即先进行column_name1排序,再进行column_name2排序,最后进行column_name3排序。

注意: 仅当多个行具有相同的column_name1时,才会对这些行按column_name2进行排序。如果column_name1中所有的值都是互不相同的,则不会按column_name2进行排序。这个对后续其他的列也是一样。

也可以按列的相对位置排序。

SELECT column_name1,  column_name2,  column_name3
FROM table_name
ORDER BY 2, 3;

其中2、3分别指 column_name2、column_name3。

降序排序(DESC)

ORDER BY语句默认为升序排序,通过添加DESC关键字,可改为降序排序。

SELECT column_name1,  column_name2,  column_name3
FROM table_name
ORDER BY column_name1 DESC, column_name2;

DESC只作用于离它最近的单个列名,若需要指定多个列使用降序排序,则应逐个添加DESC关键字。

过滤数据(WHERE)

单值检查

SELECT column_name1, column_name2
FROM table_name
WHERE column_name1 < 10
ORDER BY column_name1;

多值检查(AND、OR)

AND:当且仅当所有条件都满足时才能被检索出来。

SELECT column_name1, column_name2, column_name3
FROM table_name
WHERE column_name1 < 5 AND column_name2 <> 'Jack' AND column_name3 = 10;

OR:只要有一个条件满足就可以被检索出来。

SELECT column_name1, column_name2, column_name3
FROM table_name
WHERE column_name1 < 5 OR column_name2 <> 'Jack' OR column_name3 = 10;

注意: 当同时使用AND和OR时,AND的优先级更高。
通过使用括号(),可以改变检查顺序。

SELECT column_name1, column_name2, column_name3
FROM table_name
WHERE column_name1 < 5 AND (column_name2 <> 'Jack' OR column_name3 = 10);

不匹配检查(<>或!=)

SELECT column_name1, column_name2
FROM table_name
WHERE column_name1 <> value;

在大多数DBMS中,<>等同于!=,但相对来说<>的适用范围要更广一些。

范围检查(BETWEEN AND)

SELECT column_name1, column_name2
FROM table_name
WHERE column_name1 BETWEEN 5 AND 10;

空值检查(IS NULL)

SELECT column_name1, column_name2
FROM table_name
WHERE column_name1 IS NULL;

指定条件范围(IN)

SELECT column_name1, column_name2
FROM table_name
WHERE column_name1 IN ('Jack', 'Cabin', 'Carl')
ORDER BY column_name2;

IN的功能与OR相同。当column——name1与列表中任一值匹配时,就能被检索出来。

否定条件检查(NOT)

SELECT column_name1
FROM table_name
WHERE NOT column_name1 IS NULL;

以上语句将在表中检索所有column——name1非空的记录。
NOT的功能与<>类似,前者更多应用于更加复杂的子句。

利用通配符进行过滤(LIKE)

百分号通配符(%)

'%'表示0位、1位或多位长度的任意字符。

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

该语句会检索所有形如‘Fish…’的记录。
也可将‘%’置于中间位置。

SELECT prod_name
FROM Products
WHERE prod_name LIKE 'F%y';

下划线通配符(_)

‘_'表示任意一个字符(包括空格)。

SELECT prod_name
FROM Products
WHERE prod_id LIKE '__';

该语句将检索prod_id为两位的记录对应的prod_name。

方括号通配符([ ])

方括号通配符用来指定一个字符集,它必须匹配指定位置的一个字符(方括号中的任意一个)。

SELECT customer_name
FROM Customers
WHERE customer_name LIKE '[JM]%'
ORDER BY customer_name;

该语句将检索所有以J或M开头的名字。

否定(^)

通过使用前缀字符脱字号(^),该通配符可以表示否定。

SELECT customer_name
FROM Customers
WHERE customer_name LIKE '[^JM]%';

该语句将检索所有名字不以J和M开头的customer_name记录。
也可以使用NOT达到相同的结果。

SELECT customer_name
FROM Customers
WHERE NOT customer_name LIKE '[JM]%';

'^'相比NOT的优点是,当WHERE字句较多时,可以简化查询语句表达。

创建计算字段

本部分主要介绍如何根据表中已有数据,创建出不在表中但满足实际需要的数据格式。

拼接字段(+、||)

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

’||‘与’+‘效果相同,使用哪一个要看具体的数据库的类型。

创建别名(AS)

创建属性的别名:

SELECT vend_name+'('+vand_country+')'  AS new_vend_name
FROM Vendors
ORDER BY vend_name;

创建表的别名:

SELECT cust_name, cust_contact
FROM Customers AS C, Orders AS O, OrderItems AS OI
WHERE C.cust_id = O.cust_id
	AND OI.order_num = O.order_num
	AND prod_id = 'RGAN01';

执行算数运算

属性相减:

SELECT prod_name, order_num, total_num
FROM Products
WHERE (total_num-order_num)>0
ORDER BY prod_name;

属性相乘:

SELECT prod_id,
	   quantity,
	   item_price,
	   quantity*item_price AS expended_price
FROM OrderItems
WHERE order_nums = 20008;

函数

不同的DBMS的函数差异较大,以具体使用的DBMS为准。

常用的文本处理函数

函数说明
LENGTH()返回串的长度
UPPER()将串转换为大写
LOWER()将串转换为小写
RTRIM()去掉串右边的空格

常用的数值处理函数

函数说明
ABS()返回一个数的绝对值
COS()返回一个角的余弦
SIN()返回一个角的正弦
TAN()返回一个角的正切
SQRT()返回一个数的平方根

汇总数据(聚集函数)

计算平均值(AVG()函数)

SELECT AVG(prod_price) AS avg_price
FROM Products;

该语句将求出所有条目prod_price属性的平均值,并作为avg_price展示。

计数(COUNT()函数)

SELECT COUNT(*) AS num_cust
FROM Customers;

该语句将查询表中共有多少个条目。

对具体某列进行计数:

SELECT COUNT(cust_email) AS num_cust
FROM Customers;

注意: 对具体某列计数时会忽略NULL值,故第二种计数方式的数目小于等于第一种。

找出最大值、最小值(MAX()、MIN()函数)

SELECT MAX(prod_price) AS max_price, MIN(prod_price) AS min_price
FROM Products;

MAX()、MIN()函数均忽略值为NULL的行

求和(SUM()函数)

SELECT SUM(quantity) AS items_ordered
FROM OrderItems
WHERE order_num = 20005;

分组数据

创建分组(GROUP BY)

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

过滤分组(HAVING)

SELECT cust_id, COUNT(*) AS orders
FROM orders
GROUP BY cust_id
HAVING COUNT(*) >= 2
ORDER BY cust_id;

COUNT(*)将统计表中不同cust_id值的记录各有多少条。
HAVING和WHERE功能相似,区别在于HAVING用于分组数据(GROUP BY),WHERE用于单条数据。

联结表(JOIN)

自然联结(NATURAL JOIN)

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

虽然没有在语句中明确写出来,但该操作原理上相当于INNER JOIN。

也可以以此法联结多个表:

SELECT vend_name, prod_name, prod_price, quantity
FROM OrderItems, Vendors, Products
WHERE Vendors.vend_id = Products.vend_id
	AND OrderItems.prod_id = Products.prod_id
	AND order_num = 20007

自联结

SELECT cust_id, cust_name, cust_contact
FROM Customers
WHERE cust_name = (SELECT cust_name
	FROM Customers
	WHERE cust_contact = 'Jim Jones');

内部联结(INNER JOIN)

SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;

当使用这种明确写出联结类型的语法时,联结条件用ON子句而不是WHERE子句。

外部联结(OUTER JOIN)

分为左外联结(LEFT OUTER JOIN)右外联结(RIGHT OUTER JOIN)

SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust_id = Oreders.cust_id;

全联结(FULL OUTER JOIN)

SELECT column_name(s)
FROM table1 FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;

联合数据(UNION)

简单的联合操作

UNION相当于取多个SELECT查询结果的并集。

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'
ORDER BY cust_name, cust_contact;

注意: UNION中的每个查询必须包含完全相同的列、表达式或聚集函数。

保留重复记录(UNION ALL)

对多个查询结果中完全相同的记录,UNION默认会去掉重复的行。如果想保留这些重复的记录,可以用UNION ALL实现。

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

插入数据(INSERT)

插入完整的行

INSERT INTO Customers(cust_name, cust_id, cust_city, cust_email)
VALUES('Carl', '100100', 'Beijing', 'xxx@xxx.com');

省略的写法:

INSERT INTO Customers
VALUES('Carl', '100100', 'Beijing', 'xxx@xxx.com');

推荐使用标准写法

仅插入一部分列

INSERT INTO Customers(cust_name, cust_id)
VALUES('Carl', '100100');

其余未给出的值按具体表的定义设为NULL值或默认值,若该表既不允许有NULL值,也没有定义默认值,则DBMS会给出一条错误信息。

插入检索出的数据(INSERT+SELECT)

INSERT INTO Customers(cust_name, cust_id, cust_city, cust_email)
SELECT cust_name, cust_id, cust_city, cust_email
FROM NewCustomers;

更新、删除数据(UPDATE、DELETE)

简单的更新操作

UPDATE Customers
SET cust_contact = '123456789'
	cust_email = '123@123.com'
WHERE cust_id = '100005';

表示将id为100005的客户的电话号码改为123456789,邮箱更改为123@123.com。

简单的删除操作

DELETE FROM Customers
WHERE cust_id = '100005';

创建和操纵表(CREATE、ALTER)

简单的建表操作

CREATE TABLE Products
(
	prod_id  char(10)  NOT NULL PRIMARY KEY,
	prod_price  decimal(8,2),
	prod_desc  varchar(10)  NOT NULL DEFAULT 1
);

通过存在的表创建新表

CREATE TABLE CustCopy AS
SELECT * FROM Customers;

新增、删除列(ADD、DROP)

ALTER TABLE Vendors
ADD vend_phone char(20)
DROP COLUMN vend_phone;

注意: 不同的DBMS有不同的语法,示例中的语句并不被所有DBMS适用。

删除表(DROP TABLE)

DROP TABLE CustCopy;

重命名表

不同的DBMS差异较大,请以具体DBMS所支持的语法为准。

视图(VIEW)

视图是一个虚拟的表,它不包含任何列和数据,而是一个查询(SELECT)。
通过创建视图,我们可以重复利用SQL语句,简化操作。

创建视图(CREATE VIEW)

CREATE VIEW ProductCustomers AS
SELECT cust_name, cust_contact, prod_id
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
	AND OrderItems.order_num = Orders.order_num;
CREATE VIEW VendorLocations AS
SELECT RTRIM(vend_name)+'('+RTRIM(vend_country)+')' AS vend_title
FROM Vendors;

查看视图

与查看表的语法相同。

SELECT * FROM ProductCustomers;

删除视图(DROP VIEW)

DROP VIEW ProductCustomers;

存储过程

各DBMS存储过程的语法差异较大,下述例子均为SQL Server版本。

创建存储过程(CREATE PROCEDURE)

CREATE PROCEDURE MailingListCount
AS
DECLARE @cnt = COUNT(*) FROM Customers
WHERE NOT cust_email IS NULL
RETURN @cnt;

该存储过程中使用了DECLARE语句声明了一个名为@cnt的局部变量(SQL Server中所有局部变量都以@开头)然后在SELECT语句中使用这个变量,使它包含COUNT()函数返回的值。最后用RETURN语句来将计数返回调用程序。

CREATE PROCEDURE NewOrder @cust_id char(10)
AS
DECLARE @order_num integer
SELECT @order_num = MAX(order_num) FROM Orders
SELECT @order_num = @order_num+1
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(@order_num, GETDATE(), @cust_id)
RETURN @order_num;

该存储过程接收一个参数cust_id,局部变量@order_num表示订单号,**GETDATE()**用于获取当前系统日期。最后,用“RETURN @order_num”返回订单号。

执行存储过程(EXECUTE)

EXECUTE NewOrder(10009);

事务处理

事务处理(transaction processing) 是一种用于维护数据库完整性的机制,用来管理必须成批执行的SQL操作。它保证成批的SQL操作要么完全执行,要么完全不执行。若在执行到一半时发生错误,则进行**回退(撤销)**操作,以恢复数据库到某个已知的安全的状态。
各DBMS的事务处理语法差异较大,下述例子均为SQL Server版本。

开始事务处理(BEGIN TRANSACTION)

BEGIN TRANSACTION

提交事务处理(COMMIT TRANSACTION)

COMMIT TRANSACTION

BEGIN TRANSACTION和COMMIT TRANSACTION之间的SQL语句必须完全执行或完全不执行。

回退(ROLLBACK)

DELETE FROM Orders;
ROLLBACK;

具体使用方式见下述“保留点”。

保留点(SAVE TRANSACTION)

发生错误时会回退到这些保留点。

SAVE TRANSACTION delete1;

每个保留点都要取唯一的名字来表示,以便在回退时DBMS知道要回退到何处。如该语句中的保留点名为delete1,为了退回本例给出的保留点,在SQL Server中可如下进行:

ROLLBACK TO delete1;

完整的事务处理过程

BEGIN TRANSACTION
INSERT INTO Customers(cust_id, cust_name)
VALUES('1000000010', 'Toys Emporium');
SAVE TRANSACTION StartOrder;
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20100, '2001/12/01', 1000000010');
IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20010, 2, 'BR03', 100, 10.99);
IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;
COMMIT TRANSACTION

该事务处理包含4条INSERT语句,在第一条INSERT语句后定义一个保留点,若后边任何一个INSERT操作失败,事务处理能够回退到这里。@@ERROR变量是SQL Server中特有的检查操作是否成功的变量。若@@ERROR返回一个非0的值,则表示有错误发生。若事务处理成功,发送COMMIT TRANSACTION以保留数据。

游标

以SQL Server版本为例。

创建游标(DECLARE CURSOR)

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

DECLARE语句用于定义和命名游标,SELECT语句定义cust_email为NULL的所有客户的一个游标。

打开游标(OPEN CURSOR)

OPEN CURSOR CustCursor

关闭、释放游标(CLOSE、DEALLOCATE CURSOR)

游标在结束使用后必须被关闭,而且如果可以的话,需要释放掉游标。

CLOSE CustCursor
DEALLOCATE CURSOR CustCursor

一个具体例子

DECLARE @cust_id char(10),
		@cust_name char(50),
		@cust_address char(50),
		@cust_city char(50),
		@cust_state char(5),
		@cust_zip char(10),
		@cust_country char(50),
		@cust_contact char(50),
		@cust_email char(255),
OPEN CustCursor
-- 用游标遍历所有行,并把检索出来的值存入对应变量中
FETCH NEXT FROM CustCursor
	INTO @cust_id, @cust_name, @cust_address, 
		 @cust_city, @cust_state, @cust_zip,
		 @cust_country, @cust_contact, @cust_email
-- 当取遍所有行时停止
WHILE @@FETCH_STATUS = 0
BEGIN
-- 省略,实际情况中应包含具体的处理代码
···
FETCH NEXT FROM CustCursor
	INTO @cust_id, @cust_name, @cust_address, 
		 @cust_city, @cust_state, @cust_zip,
		 @cust_country, @cust_contact, @cust_email
END
CLOSE CustCursor

高级特性

约束(CONSTRAINT)

CREATE TABLE Vendors
(
	-- 主键约束
	vend_id  char(10)  NOT NULL PRIMARY KEY,
	-- 外键约束
	cust_id  char(10)  NOT NULL REFERENCES Customers(cust_id),
	-- 唯一约束
	cust_contact  char(20) UNIQUE,
	-- 检查约束
	quantity  integer NOT NULL CHECK(quantity>0)
)

索引(CREATE INDEX)

-- 创建索引
CREATE INDEX prod_name_ind ON PRODUCTS (prod_name);

触发器(CREATE TRIGGER)

CREATE TRIGGER customer_state ON Customers
FOR INSERT, UPDATE
AS
UPDATE Customers
SET cust_state = UPPER(cust_state)
WHERE Customers.cust_id = inserted.cust_id;

一般情况下,约束要比触发器更高效,因此应尽量使用约束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值