SQL Server进阶单表查询
Posted 沐风
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server进阶单表查询相关的知识,希望对你有一定的参考价值。
示例数据库
一条完整的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\');
以上是关于SQL Server进阶单表查询的主要内容,如果未能解决你的问题,请参考以下文章