示例:
use TSQL2012;
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;
1、執行順序
- FROM
- WHERE
- GROUP BY
- HAVING
- SELECT
- ORDER BY
查詢以SELECT子句開始,邏輯化的子句處理順序如下:
from Sales.Orders
where custid=71
group by empid,YEAR(orderdate)
having count() >1
select empid,YEAR(orderdate) as orderyear,COUNT() as numorders
order by empid,orderyear;
各子句功能:
1.從Sales.Orders表查詢行;
2.僅篩選客戶ID等於71的訂單;
3.按僱員ID和訂單年度對訂單分組;
4.僅篩選出大於1一個訂單的組
5.返回每組僱員ID、訂單年度和訂單數量;
6.按僱員ID和訂單排序輸出行。
2、查詢前10行訂單
select top 10
orderid,
orderdate,
custid,
empid
from Sales.Orders
order by orderdate desc;
3、查詢近10%的訂單
select top 10 percent
orderid,
orderdate,
custid,
empid
from Sales.Orders
order by orderdate desc;
4、開窗函數
select orderid,
custid,
val,
row_number() over(partition by custid
order by val) as rownum
from Sales.OrderValues
order by custid,val;
sql子句的邏輯處理順序
- FROM
- WHERE
- GROUP BY
- HAVING
- SELECT
* 表達式
* DISTINCT - ORDER BY
* TOP/OFFSET-FETCH
5、謂詞
- IN
select
orderid,
empid,
orderdate
from Sales.Orders
where orderid in (10248,10249,10250);
- BETWEEN
select
orderid,
empid,
orderdate
from Sales.Orders
where orderid between 10300 and 10310;
- LIKE
select
empid,
firstname,
lastname
from HR.Employees
where lastname like N'D%';
- IS NULL
- IS NOT NULL
SELECT custid,country,region,city
FROM Sales.Customers;
SELECT custid,country,region,city
FROM Sales.Customers
where region = N'WA';
SELECT custid,country,region,city
FROM Sales.Customers
where region <> N'WA';
SELECT custid,country,region,city
FROM Sales.Customers
where region is null;
SELECT custid,country,region,city
FROM Sales.Customers
where region is not null;
6、運算符
運算符優先級
- () (圓括號)
- *(乘號)、/(除號)、%(取模)
- +(正號)、-(負號)、+(加號)、+(串聯)、-(減號)
- =、>、<、>=、<=、<>、!=、!>、!<(比較運算符)
- NOT
- AND
- BETWEEN、IN、LIKE、OR
- =(賦值)
7、CASE表達式
use TSQL2012;
select productid,productname,categoryid,
case categoryid
when 1 then '一'
when 2 then '二'
when 3 then '三'
when 4 then '四'
when 5 then '五'
when 6 then '六'
when 7 then '七'
else '大於7'
end as categoryname
from Production.Products;
CASE表達式的縮寫形式:ISNULL、COALESCE、IIF、CHOOSE。
其中ISNULL存在截斷問題,只有COALESCE是標準的。
select ISNULL(null,null) as a;
select ISNULL('sqy',null) as b;
select ISNULL(null,'sqy') as c;
select COALESCE(null,null,'sqy') as a;
select COALESCE(null,'sqy',null) as b;
select COALESCE('sqy',null,null,'lqq') as c;
select COALESCE(null,null,null,'lqq') as d;
8、字符數據
1)、數據類型
- 常規:每個字符使用1個字節存儲,限制除英語外僅能使用一種語言。
CHAR、VARCHAR
示例:‘This is a regular character string literal’ - Unicode:每個字符使用2個字節存儲,可以支持多種語言。
NCHAR、NVARCHAR
示例:N’This is a Unicode character string literal’
CHAR/NCHAR具有固定長度;VARCHAR/NVARCHAR具有可變長度。
VARCHAR(MAX)、NVARCHAR(MAX),最大默認字節數爲8000。
1)、運算符和函數
- 字符串連接
加號運算符(+)和CONCAT函數。
use TSQL2012;
select empid,firstname,lastname,firstname + lastname as fullname
from HR.Employees;
標準SQL裏面規定了連接NULL的結果應爲NULL,這是SQL Server的默認行爲。例如:
select custid,country,region,city,
country + N',' + region + N',' + city as location
from Sales.Customers;
解決一:使用COALESCE函數
--使用空字符串替換NULL
select custid,country,region,city,
country + coalesce(N','+region,N'') + N',' + city as location
from Sales.Customers;
解決二:使用CONCAT函數:接收一個連續的輸入列表並自動以空格字符串替換NULL。(SQL Server2012添加)
select custid,country,region,city,
CONCAT(country,N','+region,N','+city) as location
from Sales.Customers;
- SUBSTRING函數
- LEFT和RIGHT函數
語法:LEFT(string,n),RIGHT(string,n)
- LEN和DATALENGTH函數
語法:LEN(string)
注意:1)LEN函數返回的輸入字符串中的字符數,但不一定是字節數。對於常規字符,每個字符需要一個存儲字節,字符數和字節數是相同的。對於Unicode字符,每個字符需要兩個存儲字節(大多數請款是這樣),因此字符數是字節數的一半。要獲取字節數可以使用DATALENGHT函數。
2)LEN和LENGTH另一個區別是,LEN會刪除尾隨空格但是DATALENGTH不會。
select N'string ' as 'Unicode字符串',
LEN(N'string ') as 'Unicode字符',
DATALENGTH(N'string ') as 'Unicode字節',
'string ' as '常規字符串',
LEN('string ') as '常規字符',
DATALENGTH('string ') as '常規字節';
- CHAINDEX
返回字符串再字符串中第一次出現的位置。
- PATINDEX函數
語法:PATINDEX(partter,string)
參數partter使用T-SQL中like謂詞類似模式。
返回模式在字符串中第一次出現的位置。
- REPLACE函數
語法:REPLACE(string,substring1,substring2)
使用string2替換string中出現的substring1。
可以用於計算某個字符在字符串內出現的次數。
select empid,lastname,
LEN(lastname)-LEN(REPLACE(lastname,'e','')) as numoccur
from HR.Employees;
- REPLICATE函數
語法:REPLICATE(string,n)
-- 生成一個具有前導"0",代表供應商ID的10位數字符串。
select supplierid,
RIGHT(REPLICATE('0',9) + cast(supplierid as varchar(10)),10) as strsupplierid
from
Production.Suppliers;
- STUFF函數
允許從字符串中移除指定數量的字符,並插入一個替代的新字符串。
語法:STUFF(sting,pos,delete_length,insertstring)
select STUFF('xzf',2,1,'abc');
- UPPER和LOWER
UPPER:返回輸入字符串的全部大寫。
LOWER:返回輸入字符串的全部小寫。
- RTRIM和LTRIM
刪除字符串尾隨和前導空格
select RTRIM(' abc '),LTRIM(' abc '),RTRIM(LTRIM(' abc '));