sqlserver

字段

添加字段

例如,假设我们有一个名为 students 的表,现在要添加一个名为 age 的列,数据类型为整数(INT)。可以使用以下 SQL 语句进行操作:

ALTER TABLE students
ADD age INT;

执行上述语句后,students 表将新增一个名为 age 的列,可以用来存储学生的年龄信息。

char和nvarchar和varchar

char
char:char是固定长度的字符数据类型。当定义一个char列时,需要指定该列能够存储的字符数量。如果实际存储的字符数少于指定长度,剩余空间将用空格字符填充。例如,定义一个长度为10的char列,如果存储字符串"Hello",则剩余的5个字符会填充为空格,占用总共10个字符的存储空间。

在数据库中,nvarchar和varchar是用于存储字符数据的数据类型。它们之间的区别在于字符编码存储方式

varchar:

varchar是可变长度字符类型,用于存储可变长度的非Unicode字符数据
它占用的存储空间是根据存储的实际字符长度来动态分配的。
varchar可以存储ASCII字符集中的字符,包括字母、数字、符号等。

nvarchar:

nvarchar也是可变长度字符类型,用于存储可变长度的Unicode字符数据
它占用的存储空间是根据存储的实际字符长度和编码方案(通常是UTF-16)来动态分配的。
nvarchar可以存储任何Unicode字符,包括多种语言字符集、特殊符号、表情符号等。

区别:

编码:varchar使用非Unicode编码(如ASCII),而nvarchar使用Unicode编码(通常是UTF-16)。
存储空间:由于Unicode字符需要更多的存储空间来表示,nvarchar在存储相同字符数量时通常需要比varchar更多的存储空间。
跨语言支持:由于nvarchar支持Unicode编码,它能够存储各种语言的字符集,包括非常规字符集

应用场景:
nvarchar常用于存储多语言、多字符集、特殊字符等需求较广泛的情况,而varchar适用于存储英文字符为主的数据或存储占用空间较为关键的场景。

中文字符占用char个数

在大多数情况下,数据库中的 char 字段使用固定长度的存储,每个字符都占用指定的字节数。在英文字符使用 ASCII 编码的情况下,一个 char 字符通常占用1个字节的存储空间

然而,对于中文字符,情况会有所不同。在一些字符编码中,如 UTF-8 或 UTF-16,一个中文字符通常占用多个字节的存储空间。具体占用的字节数取决于所采用的字符编码和数据库的设置。

例如,在使用 UTF-8 编码的情况下,一个中文字符通常占用3个字节的存储空间。而在使用 UTF-16 编码的情况下,一个中文字符通常占用2个字节的存储空间。

所以,如果数据库的字段类型为 char,并且使用了支持多字节字符的字符编码,一个中文字符可能占用多个 char 的存储空间。具体需要占用多少个 char 取决于数据库的设置和字符编码。

添加约束

在 SQL 数据库中,约束(Constraint)用于定义对表中数据的限制条件,以保证数据的完整性、一致性和有效性。通过定义约束,可以对表中的列或列的组合施加规则,确保数据符合预期的要求。以下是几个常见的约束类型及其示例:

主键约束(Primary Key Constraint):

主键约束用于标识表中的唯一记录,并且要求该列的值不为空
例如,创建一个名为 “students” 的表,其中的 “student_id” 列被定义为主键,确保每个学生的学号是唯一非空的。

ALTER TABLE students
ADD CONSTRAINT pk_students PRIMARY KEY (student_id);
/*
student_id是表中的某一个字段,pk_stuednts是我们添加的某一个约束的名称
*/

唯一约束(Unique Constraint):

唯一约束用于确保表中某一列或列的组合的值是唯一的。
例如,在一个 “employees” 表中,可以创建一个唯一约束来确保员工的邮箱地址是唯一的。

ALTER TABLE employees
ADD CONSTRAINT uq_email UNIQUE (email);
/*
email是原本在表中的一个字段,uq_email是我们自己添加的约束的名称
*/

外键约束(Foreign Key Constraint):

外键约束用于建立表之间的关系,确保一个表的列值另一个表的列值之间的一致性
例如,在一个 “orders” 表中,可以创建一个外键约束,将该表的 “customer_id” 列与 “customers” 表中的 “customer_id” 列关联起来,确保每个订单都有一个有效的客户ID。

ALTER TABLE orders
ADD CONSTRAINT fk_orders_customers
FOREIGN KEY (customer_id) REFERENCES customers(customer_id);
/*
ALTER TABLE orders:指定要修改的表为 "orders" 表。
ADD CONSTRAINT fk_orders_customers:定义要添加的约束的名称为 "fk_orders_customers"。
FOREIGN KEY (customer_id):指定要作为外键的列为 "customer_id"。
REFERENCES customers(customer_id):指定外键引用的目标表和列,其中 "customers" 是目标表,"customer_id" 是目标列。
*/

非空约束(Not Null Constraint):

非空约束用于确保表中的某一列不允许为空值
例如,在一个 “products” 表中,可以对 “product_name” 列应用非空约束,以确保每个产品都有一个名称。

ALTER TABLE products
ALTER COLUMN product_name SET NOT NULL;

检查约束(Check Constraint):

检查约束用于定义列的取值范围或条件,以确保插入或更新的数据满足特定的条件。
例如,在一个 “employees” 表中,可以创建一个检查约束来限制员工的年龄必须在特定范围内。
通过使用约束,可以在数据库层面对数据进行验证和保护,避免不符合规定的数据被插入或更新,从而提高数据的质量和一致性。

ALTER TABLE employees
ADD CONSTRAINT ck_age CHECK (age BETWEEN 18 AND 60);
/*
ck_age是我们自己添加的约束的名称,而age是表中的字段的名称
*/

默认值约束

要添加默认值的约束,可以使用 ALTER TABLE 语句的 ALTER COLUMN 子句,并指定要添加默认值的列和默认值。下面是一个示例:

ALTER TABLE record
ADD CONSTRAINT  df_bd  DEFAULT  getdate( )  FOR  borrow_date 
/*
record表中,添加约束名df_bd默认值为获取当前的时间,对borrow_date这个字段
*/

以上示例中,products 表的 price 列将被设置为默认值 0.00。这意味着,当向表中插入新记录时,如果未指定 price 的值,将自动使用默认值 0.00。

在创建表的时候添加主键约束和外键约束

use JY
go
create table record
(
reader_id char(8) not null,
book_id char(8) not null,
borrow_date date not null,
notes nvarchar(50) not null,
primary key (reader_id,book_id),
constraint fk_reader foreign key (reader_id) references reader(reader_id),
constraint fk_book foreign key (book_id) references book(book_id),
)
go

取消掉约束

ALTER TABLE orders
DROP CONSTRAINT fk_orders_customers;
/*
fk_orders_customers表示的是约束的名称
*/

标识列(Identity Column)

创建表时设置标识列

数据库表中的标识列(Identity Column)用于自动生成唯一的数值标识符。它通常用作表的主键,以确保每个记录都具有唯一的标识。标识列的值是由数据库自动分配和管理的,通常采用递增的方式生成。

注意:

1.一个表只能有一列定义为IDENTITY属性,而且该列的数据类型必须为数值型。
2.标识列不允许空值,也不能有检查约束。

以下是一个示例,展示了如何在 SQL Server 中创建一个带有标识列的表:

CREATE TABLE customers
(
    customer_id INT IDENTITY(1,1) PRIMARY KEY,
    customer_name VARCHAR(100),
    email VARCHAR(100)
);

在上述示例中,创建了一个名为 customers 的表,其中的 customer_id 列被定义为标识列。通过指定 IDENTITY(1,1),表示从 1 开始递增,每次递增 1。该列还被指定为主键,以确保每个客户都具有唯一的标识符。

当向带有标识列的表中插入新记录时,数据库会自动为该列生成唯一的值,无需手动指定。例如:

INSERT INTO customers (customer_name, email)
VALUES ('John Smith', 'john@example.com');

在执行上述插入语句时,数据库会自动生成一个唯一的标识值并插入到 customer_id 列中。

标识列的好处是可以简化数据的管理和维护,确保每个记录都具有唯一的标识符。它常用于主键列或需要唯一标识符的场景,如关联表和数据关系的建立。

添加数据

insert into

INSERT INTO 表名 (1,2,3, ...)
VALUES (1,2,3, ...)

请注意以下事项:

将 "表名" 替换为要添加数据的表的实际名称。
在括号中,指定要添加数据的列的列表。如果要为所有列添加数据,可以省略列名。
在 VALUES 子句中,按相同的顺序提供与列对应的值。
如果列具有默认值,并且您不想为其提供值,请省略对应的列。
如果列是自增标识列(IDENTITY),则无需为其提供值。

以下是一个具体的示例,假设有一个名为 “employees” 的表,包含列 “employee_id”、“first_name” 和 “last_name”:

INSERT INTO employees (first_name, last_name)
VALUES ('John', 'Doe')

这将在 “employees” 表中添加一条记录,将 “first_name” 设置为 ‘John’,将 “last_name” 设置为 ‘Doe’。如果 “employee_id” 是自增标识列,它将自动生成一个唯一的值。

select into

SELECT INTO 语句用于从一个表中选择数据,并将其插入到一个新表中。新表的结构将根据 SELECT 语句中选择的列和数据类型自动创建。SELECT INTO 语句可以用于创建包含选定数据的新表。

SELECT1,2,3, ...
INTO 新表名
FROM 源表

请注意以下事项:

将 "列1, 列2, 列3, ..." 替换为要从源表中选择的列的列表。
将 "新表名" 替换为要创建的新表的名称。
将 "源表" 替换为要从中选择数据的源表的名称。

下面是一个具体的示例,假设有一个名为 “customers” 的表,包含列 “customer_id”、“first_name” 和 “last_name”:

SELECT customer_id, first_name, last_name
INTO new_customers
FROM customers

这将从 “customers” 表中选择 “customer_id”、“first_name” 和 “last_name” 列的数据,并将其插入到名为 “new_customers” 的新表中。新表将具有与源表相同的列和相同的数据类型。

通过 SELECT INTO 语句,您可以根据源表的数据创建新表,并选择性地将特定列的数据复制到新表中。这在需要从现有表中提取数据并创建新的工作表或报表时非常有用。

删除数据

删除指定行

假设有一个名为 employees 的表,其中包含以下列:employee_id、first_name、last_name、email。现在要删除 employees 表中 employee_id 为 1001 的员工记录。

DELETE FROM employees
WHERE employee_id = 1001;

上述语句将从 employees 表中删除满足条件的记录,即 employee_id 等于 1001 的记录将被删除。

删除所有行

如果要删除表中的所有数据,可以省略 WHERE 子句,如下所示:

DELETE FROM employees;

上述语句将删除 employees 表中的所有记录,表结构保持不变。

TRUNCATE语句

TRUNCATE 语句用于快速删除表中的所有数据,而不是删除整个表。它具有以下特点:

  1. TRUNCATE 是一种快速删除数据的方法,比使用 DELETE 语句效率更高
  2. TRUNCATE 删除表中的所有行,但保留表的结构、索引、约束等定义。
  3. TRUNCATE 操作无法回滚,一旦执行就不可撤销,所以在使用 TRUNCATE 之前请确保备份了重要的数据。

下面是 TRUNCATE 语句的基本语法:

TRUNCATE TABLE table_name;

其中,table_name 是要删除数据的表的名称。

更新数据

将图书表book中interviews_times列的值改为0

USE JY
GO
UPDATE book
SET interview_times='0'
GO
SELECT * FROM book
GO

更新图书表book中“电子工业出版社”的interviews_times列值为10

USE JY
GO
UPDATE book
SET interview_times='10'
WHERE book_publisher='电子工业出版社'

查询数据

返回查询结果的前n(%)行

SELECT TOP n *返回查询结果的前n行。
SELECT TOP n PERCENT *返回查询结果的前n%行

查询图书表book的所有信息,只显示查询结果的前5行数据。

USE JY
GO
SELECT TOP 5 *   
FROM book
GO

消除查询结果的重复行

ISTINCT关键字用于消除SELECT语句的查询结果集的重复行。默认的ALL关键字,将返回所有行,包括值相同的重复行。

SELECT DISTINCT book_publisher
FROM book

在查询结果中增加要显示的字符串

为了使查询结果更加容易理解,可以在SELECT语句的查询列名列表中使用单引号为特定的列添加注释。

举例:
查询数据表book的借阅次数的总和,要求查询结果显示为“总借阅次数: 309”。

USE JY
GO
SELECT ‘总借阅次数:’ , SUM(interview_times)     
FROM book
GO

使用聚合函数

count

在读者表reader中统计读者总人数。

USE JY
GO
SELECT COUNT(*)    --使用聚合函数查询
FROM reader
GO

从运行结果我们可以看到,结果输出无列名。因为SELECT语句后面给出的是COUNT函数而不是表的列名。这时,我们需要用AS给出一个别名。

USE JY
GO
SELECT COUNT(*) AS '读者数'
GO

使用WHERE子句限制查询条件

WHERE子句常用运算符
使用LIKE实现模糊查询

举例:
查询读者表reader中所有姓“王”的读者的信息。

USE JY
GO
SELECT *
FROM reader
WHERE reader_name LIKE '李%' 
GO
查询列值为空的数据行

在WHERE子句中使用IS NULL,可以查询列值为空的记录。与IS NULL相反的是IS NOT NULL,用于查询列值不为空的记录。

举例:
查询图书表book中notes列值为空的记录。

USE JY
GO
SELECT *
FROM record
WHERE notes IS NULL    
GO

使用ORDER BY子句重新排序查询结果

可以按升序(ASC)排序,也可以按降序排序(DESC),系统默认按升序排序。

查询图书表book中所有图书信息,并按借阅次数由高到低进行排序。

USE JY
GO
SELECT *
FROM BOOK
ORDER BY interview_times DESC
GO

使用GROUP BY子句分组或统计查询结果

GROUP BY子句的作用是把查询得到的数据集按分组属性划分为若干组,同一个组内所有记录在分组属性上是相同的,在此基础上,使用HAVING子句再对每一组使用聚合函数进行分类汇总

举例:
在图书表book中统计各出版社出版图书的总数。

USE JY
GO
SELECT book_publisher,count(book_publisher)AS’图书总数’
FROM book
GROUP BY book_publisher
GO

举例:
在图书表book中查询图书借阅次数在20次以上,而且出版图书总数大于1的出版社。

USE JY
GO
SELECT book_publisher
FROM book
WHERE interview_times>20
GROUP BY book_publisher HAVING count(book_publisher)>1
GO

使用子查询

使用比较运算符的子查询

子查询可以使用比较运算符,例如,=(等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、<>或!=(不等于)、!>(不大于)、!<(不小于)。

举例:
查询没有借阅编号为“b0005”这本书的读者姓名

USE JY
GO
SELECT reader_name
FROM reader
WHERE reader_id
<>( SELECT reader_id
     FROM record
     WHERE book_id='b0005' )
GO
使用IN关键字的子查询

使用IN关键字进行子查询时,内层查询语句返回一个数据列值,提供给外层查询进行比较操作。

举例:
查询借阅至少2本书的读者姓名。

USE JY
GO
SELECT reader_name
FROM reader
WHERE reader_id
IN( SELECT reader_id
  FROM record
  GROUP BY reader_id HAVING COUNT (reader_id)>=2)
GO
使用ANY、SOME和ALL关键字的子查询

ANY、SOME和ALL关键字的区别:
1)ANY和SOME关键字是同义词,接在一个比较运算符后面,表示与内层查询的返回值列表进行比较,只要满足内层查询中的任何一个条件,就返回TRUE。
2)ALL关键字接在一个比较运算符后面,表示与内层查询的返回值列表进行比较,只有同时满足内层查询中的所有条件,才返回TRUE

举例:
查询借阅次数最多和最少的图书编号。
注意:UNION 是用于合并两个或多个 SELECT 查询结果集的关键字

USE JY
GO
SELECT book_id 
FROM book
WHERE interview_times
=any (SELECT MAX(interview_times) FROM book
       UNION
     SELECT MIN(interview_times) FROM book)
GO
使用EXISTS关键字的子查询

1)EXISTS关键字后面的参数是一个任意的子查询,当内层查询结果至少返回一个数据行时**,EXISTS的结果为TRUE。此时,外层查询将进行查询,否则,外层查询语句将不进行查询。**

2)NOT EXISTS与EXISTS使用方法相同,返回的结果相反。当内层查询结果至少返回一个数据行时,NOT EXISTS的结果为FALSE。此时,外层查询将不进行查询,否则,外层查询语句将进行查询。

举例:

查询借阅过图书编号为“b0002”图书的读者编号和姓名。

use JY
select reader_id,reader_name
from reader
where exists
(
select * from record where book_id='b0002' and reader_id = reader.reader_id
)

在给定的 SQL 查询语句中,WHERE reader_id=reader.reader_id 是一个连接条件,用于将外部查询(reader 表)和子查询(record 表)关联起来。通过这个条件,外部查询可以检查是否存在满足条件的记录。

在这种情况下,如果去掉 WHERE reader_id=reader.reader_id,外部查询将无法与子查询建立关联,从而无法正确过滤出满足条件的结果。

使用自然连接查询数据

自连接查询是一个表和它自身进行连接,是多表连接的特殊情况。

为了查询同名的读者,我们采用自连接查询。为了方便查询时对表列的引用,简化连接条件的书写,我们先在FROM子句中为读者表reader分别定义了两个不同的别名,然后使用这两个别名写出一个连接条件,

use JY
select r1.reader_name,r1.reader_department
from reader as r1,reader as r2
where r1.reader_name=r2.reader_name and r1.reader_id<>r2.reader_id

创建视图

CREATE VIEW语句创建视图

举例:
创建视图,用于查看借阅次数大于30次的图书信息

USE JY
GO
CREATE VIEW v_book
AS 
  SELECT *
  FROM book 
  WHERE interview_times>30
GO

查询

exists 和 not exists

在SQL中,EXISTS和NOT EXISTS是用于进行存在性检查的谓词(Predicate)。它们用于确定子查询是否返回了结果,从而判断是否满足某个条件。下面我会解释这两个谓词的含义并举例说明。

  1. EXISTS:EXISTS谓词用于检查子查询是否返回了至少一行结果。如果子查询返回至少一行,则EXISTS返回真(True),否则返回假(False)。

举例说明:
假设我们有两个表:学生表(Students)和成绩表(Grades)。我们想要找出至少有一门课程成绩及格的学生。可以使用EXISTS来实现:

SELECT *
FROM Students s
WHERE EXISTS (
    SELECT *
    FROM Grades g
    WHERE g.student_id = s.student_id
    AND g.score >= 60
);

在这个例子中,子查询检查成绩表中是否存在某个学生的成绩满足大于等于60分的条件。如果存在至少一行满足条件的成绩记录,那么主查询就会返回该学生的信息。

  1. NOT EXISTS:NOT EXISTS谓词与EXISTS相反,用于检查子查询是否不返回任何结果。如果子查询不返回任何行,则NOT EXISTS返回真(True),否则返回假(False)。

举例说明:
假设我们有两个表:学生表(Students)和选课表(CourseSelection)。我们想要找出没有选修课程的学生。可以使用NOT EXISTS来实现:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值