SQL Server进阶(3)单表查询
示例数据库
一条完整的sql语句
select top | distinct 字段, 表达式, 函数, ... from 表表达式 where 筛选条件 group by 分组条件 having 筛选条件 order by 排序依据;
SQL的执行顺序:
运算符的优先级
SELECT语句的元素
SELECT empid, YEAR(orderdate) AS orderyear, COUNT(*) AS numorders FROM Sales.Orders WHERE custid = 71 GROUP BY empid, YEAR(orderdate) HAVING COUNT(*) > 1 ORDER BY empid, orderyear;
FROM子句
WHERE子句
GROUP BY子句
SELECT empid, YEAR(orderdate) AS orderyear, SUM(freight) AS totalfreight, COUNT(*) AS numorders FROM Sales.Orders WHERE custid = 71 GROUP BY empid, YEAR(orderdate);
除了COUNT(*)之外,所有聚合函数忽略NULL标记。
DISTINCT去重
SELECT empid, YEAR(orderdate) AS orderyear, COUNT(DISTINCT custid) AS numcusts FROM Sales.Orders GROUP BY empid, YEAR(orderdate);
HAVING子句
HAVING语句通常与GROUP BY语句联合使用,用来过滤由GROUP BY语句返回的记录集。
HAVING语句的存在弥补了WHERE关键字不能与聚合函数联合使用的不足。
SELECT empid, YEAR(orderdate) AS orderyear FROM Sales.Orders WHERE custid = 71 GROUP BY empid, YEAR(orderdate) HAVING COUNT(*) > 1;
SELECT子句
ORDER BY子句
SELECT empid, YEAR(orderdate) AS orderyear, COUNT(*) AS numorders FROM Sales.Orders WHERE custid = 71 GROUP BY empid, YEAR(orderdate) HAVING COUNT(*) > 1 ORDER BY empid, orderyear;
TOP和OFFSET-FETCH筛选
PERCENT
SELECT TOP (1) PERCENT orderid, orderdate, custid, empid FROM Sales.Orders ORDER BY orderdate DESC;
WITH TIES
SELECT TOP (5) WITH TIES orderid, orderdate, custid, empid FROM Sales.Orders ORDER BY orderdate DESC;
OFFSET-FETCH筛选(跳过50取25)
SELECT orderid, orderdate, custid, empid FROM Sales.Orders ORDER BY orderdate, orderid OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY;
开窗函数
SELECT orderid, custid, val, ROW_NUMBER() OVER(PARTITION BY custid ORDER BY val) AS rownum FROM Sales.OrderValues ORDER BY custid, val;
谓词和运算符
CASE表达式
① 简单表达式:将一个值与一组可能的取值进行比较,并返回满足第一个匹配的结果;
SELECT productid,productname,categoryid,categoryname=( CASE categoryid WHEN 1 THEN 'Beverages' WHEN 2 THEN 'Condiments' WHEN 3 THEN 'Confections' WHEN 4 THEN 'Dairy Products' ELSE 'Unkonw Category' END) FROM Production.Products;
② 搜索表达式:将返回结果为TRUE的第一个WHEN逻辑表达式所关联的THEN子句中指定的值。如果没有任何WHEN表达式结果为TRUE,CASE表达式则返回ELSE子句中出现的值。(如果没有指定ELSE,则默认返回NULL);
SELECT orderid, custid, val, valuecategory=( CASE WHEN val < 1000.00 THEN 'Less than 1000' WHEN val BETWEEN 1000.00 AND 3000.00 THEN 'Between 1000 and 3000' WHEN val > 3000.00 THEN 'More than 3000' ELSE 'Unknown' END ) FROM Sales.OrderValues
NULL标记
同时操作
使用字符数据
SELECT SUBSTRING('abcde', 1, 3); -- 'abc' SELECT RIGHT('abcde', 3); -- 'cde' SELECT LEN(N'abcde'); -- 5 SELECT DATALENGTH(N'abcde'); -- 10 SELECT CHARINDEX(' ','Itzik Ben-Gan'); -- 6 SELECT PATINDEX('%[0-9]%', 'abcd123efgh'); -- 5 SELECT REPLACE('1-a 2-b', '-', ':'); -- '1:a 2:b' SELECT empid, lastname, LEN(lastname) - LEN(REPLACE(lastname, 'e', '')) AS numoccur FROM HR.Employees; SELECT REPLICATE('abc', 3); -- 'abcabcabc' SELECT supplierid, RIGHT(REPLICATE('0', 9) + CAST(supplierid AS VARCHAR(10)), 10) AS strsupplierid FROM Production.Suppliers; SELECT STUFF('xyz', 2, 1, 'abc'); -- 'xabcz' SELECT UPPER('Itzik Ben-Gan'); -- 'ITZIK BEN-GAN' SELECT LOWER('Itzik Ben-Gan'); -- 'itzik ben-gan' SELECT RTRIM(LTRIM(' abc ')); -- 'abc' SELECT FORMAT(1759, '0000000000'); -- '0000001759'
日期和时间

-- Current Date and Time SELECT GETDATE() AS [GETDATE], CURRENT_TIMESTAMP AS [CURRENT_TIMESTAMP], GETUTCDATE() AS [GETUTCDATE], SYSDATETIME() AS [SYSDATETIME], SYSUTCDATETIME() AS [SYSUTCDATETIME], SYSDATETIMEOFFSET() AS [SYSDATETIMEOFFSET]; SELECT CAST(SYSDATETIME() AS DATE) AS [current_date], CAST(SYSDATETIME() AS TIME) AS [current_time]; -- The CAST, CONVERT and PARSE Functions and their TRY_ Counterparts SELECT CAST('20090212' AS DATE); SELECT CAST(SYSDATETIME() AS DATE); SELECT CAST(SYSDATETIME() AS TIME); SELECT CONVERT(CHAR(8), CURRENT_TIMESTAMP, 112); SELECT CAST(CONVERT(CHAR(8), CURRENT_TIMESTAMP, 112) AS DATETIME); SELECT CONVERT(CHAR(12), CURRENT_TIMESTAMP, 114); SELECT CAST(CONVERT(CHAR(12), CURRENT_TIMESTAMP, 114) AS DATETIME); SELECT PARSE('02/12/2007' AS DATETIME USING 'en-US'); SELECT PARSE('02/12/2007' AS DATETIME USING 'en-GB'); -- SWITCHOFFSET SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(), '-05:00'); SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(), '+00:00'); -- TODATETIMEOFFSET /* UPDATE dbo.T1 SET dto = TODATETIMEOFFSET(dt, theoffset); */ -- DATEADD SELECT DATEADD(year, 1, '20090212'); -- DATEDIFF SELECT DATEDIFF(day, '20080212', '20090212'); SELECT DATEADD( day, DATEDIFF(day, '20010101', CURRENT_TIMESTAMP), '20010101'); SELECT DATEADD( month, DATEDIFF(month, '20010101', CURRENT_TIMESTAMP), '20010101'); SELECT DATEADD( month, DATEDIFF(month, '20091231', CURRENT_TIMESTAMP), '20091231'); -- DATEPART SELECT DATEPART(month, '20090212'); -- DAY, MONTH, YEAR SELECT DAY('20090212') AS theday, MONTH('20090212') AS themonth, YEAR('20090212') AS theyear; -- DATENAME SELECT DATENAME(month, '20090212'); SELECT DATENAME(year, '20090212'); -- ISDATE SELECT ISDATE('20090212'); SELECT ISDATE('20090230'); -- fromparts SELECT DATEFROMPARTS(2012, 02, 12), DATETIME2FROMPARTS(2012, 02, 12, 13, 30, 5, 1, 7), DATETIMEFROMPARTS(2012, 02, 12, 13, 30, 5, 997), DATETIMEOFFSETFROMPARTS(2012, 02, 12, 13, 30, 5, 1, -8, 0, 7), SMALLDATETIMEFROMPARTS(2012, 02, 12, 13, 30), TIMEFROMPARTS(13, 30, 5, 1, 7); -- EOMONTH SELECT EOMONTH(SYSDATETIME());
查询元数据

-- Catalog Views USE TSQL2012; SELECT SCHEMA_NAME(schema_id) AS table_schema_name, name AS table_name FROM sys.tables; SELECT name AS column_name, TYPE_NAME(system_type_id) AS column_type, max_length, collation_name, is_nullable FROM sys.columns WHERE object_id = OBJECT_ID(N'Sales.Orders'); -- Information Schema Views SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = N'BASE TABLE'; SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLLATION_NAME, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = N'Sales' AND TABLE_NAME = N'Orders'; -- System Stored Procedures and Functions EXEC sys.sp_tables; EXEC sys.sp_help @objname = N'Sales.Orders'; EXEC sys.sp_columns @table_name = N'Orders', @table_owner = N'Sales'; EXEC sys.sp_helpconstraint @objname = N'Sales.Orders'; SELECT SERVERPROPERTY('ProductLevel'); SELECT DATABASEPROPERTYEX(N'TSQL2012', 'Collation'); SELECT OBJECTPROPERTY(OBJECT_ID(N'Sales.Orders'), 'TableHasPrimaryKey'); SELECT COLUMNPROPERTY(OBJECT_ID(N'Sales.Orders'), N'shipcountry', 'AllowsNull');
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2018-01-15 设计模式的艺术
2017-01-15 高并发数据库之MySql性能优化实战总结