SQL Server进阶(三)单表查询

时间:2021-11-27 11:25:26

示例数据库

  点我下载

一条完整的sql语句

select top | distinct   字段, 表达式, 函数, ...
from 表表达式
where 筛选条件
group by 分组条件
having 筛选条件
order by 排序依据;

SQL的执行顺序:

  SQL Server进阶(三)单表查询SQL Server进阶(三)单表查询

运算符的优先级

SQL Server进阶(三)单表查询

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;

SQL Server进阶(三)单表查询

SQL Server进阶(三)单表查询

FROM子句

SQL Server进阶(三)单表查询

WHERE子句

SQL Server进阶(三)单表查询

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子句

SQL Server进阶(三)单表查询SQL Server进阶(三)单表查询

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;

SQL Server进阶(三)单表查询

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;

谓词和运算符

SQL Server进阶(三)单表查询

SQL Server进阶(三)单表查询

SQL Server进阶(三)单表查询

CASE表达式

SQL Server进阶(三)单表查询

① 简单表达式:将一个值与一组可能的取值进行比较,并返回满足第一个匹配的结果;

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标记

SQL Server进阶(三)单表查询

同时操作

SQL Server进阶(三)单表查询

使用字符数据

SQL Server进阶(三)单表查询

SQL Server进阶(三)单表查询

SELECT SUBSTRING('abcde', 1, 3); -- 'abc'

SELECT RIGHT('abcde', 3); -- 'cde'

SELECT LEN(N'abcde'); --

SELECT DATALENGTH(N'abcde'); --

SELECT CHARINDEX(' ','Itzik Ben-Gan'); --

SELECT PATINDEX('%[0-9]%', 'abcd123efgh'); --

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('', 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, ''); -- '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('' 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, ''); -- DATEDIFF
SELECT DATEDIFF(day, '', ''); SELECT
DATEADD(
day,
DATEDIFF(day, '', CURRENT_TIMESTAMP), ''); SELECT
DATEADD(
month,
DATEDIFF(month, '', CURRENT_TIMESTAMP), ''); SELECT
DATEADD(
month,
DATEDIFF(month, '', CURRENT_TIMESTAMP), ''); -- DATEPART SELECT DATEPART(month, ''); -- DAY, MONTH, YEAR SELECT
DAY('') AS theday,
MONTH('') AS themonth,
YEAR('') AS theyear; -- DATENAME
SELECT DATENAME(month, ''); SELECT DATENAME(year, ''); -- ISDATE
SELECT ISDATE('');
SELECT ISDATE(''); -- 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');