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());
View Code

 查询元数据

-- 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\');
View Code

 

以上是关于SQL Server进阶单表查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server学习笔记——单表查询

SQL Server学习笔记——单表查询

Microsoft SQL Server 代码片段收集

Django---进阶5

Django---进阶5

SQL Server进阶查询