SQL 語句及關鍵字的用法


一、SELECT

select [ALL|DISTINCT] select_list
[into new table]
FROM table_source
[where serch_conditaion]
[GROUP BY group_by_expression]
[Having serch_conditaion]
[Order by order_expression[ASC|DESC]]
--從上面的語句可以看出SELECT 查詢語句共有5個子句 其中SELECT\FROM 為必選語句
--SELECT 子句:用來指定由查詢返回的列
--ALL|DISTINCT:用來指定對查詢結果集,相同行的處理方式,ALL-為所有 DISTINCT:保留一條記錄
--select_list:用來顯示要顯示的目標列,全部可以用 * 代替,不是全部每個列字段用,分割
--into new table:用來創建一個新的臨時表
--FROM table_source:指定查詢的數據源
--where serch_conditaion:用來限定返回行的搜索條件
--GROUP BY group_by_expression]:用來指定查到結果的分組條件
--Having serch_conditaion:用來指定組成或聚合的搜索條件
--Order by order_expression[ASC|DESC]:用來指定結果集的排序方式

二、PIVOT  行轉列

注意:PIVOT、UNPIVOT是SQL Server 2005 的語法,使用需修改數據庫兼容級別
 
在數據庫屬性->選項->兼容級別改為   90

PIVOT用於將列值旋轉為列名(即行轉列),在SQL Server 2000可以用聚合函數配合CASE語句實現

PIVOT的一般語法是:PIVOT(聚合函數(列) FOR 列 in (…) )AS P

完整語法:

table_source      --數據源

PIVOT(

聚合函數(value_column)  --統計轉化行值的聚合函數值

FOR pivot_column           --需要轉化的行列名

IN(<column_list>)           --行值得結合

)

典型實例:

1、建立表格

ifobject_id('tb')isnotnulldroptabletb

go

create table tb (姓名varchar(10),課程varchar(10),分數int)

insert into tb values ('張三','語文',74)

insert into tb values ('張三','數學',83)

insert into tb values ('張三','物理',93)

insertintotbvalues ('李四','語文',74)

insert into tb values ('李四','數學',84)

insert into tb values ('李四','物理',94)

go

select * from tb

go

姓名       課程       分數

---------- ---------- -----------

張三       語文        74

張三       數學        83

張三       物理        93

李四       語文        74

李四       數學        84

李四       物理        94

 

2、使用SQL Server 2000靜態SQL

--c

select姓名,

 max(case 課程 when '語文' then 分數 else 0 end)語文,

 max(case 課程 when '數學' then 分數 else 0 end)數學,

 max(case 課程 when '物理' then 分數 else 0 end)物理

from tb

group by 姓名

姓名       語文        數學        物理

---------- ----------- ----------- -----------

李四        74          84          94

張三        74          83          93

 3、使用SQL Server 2005靜態SQL

select*fromtb pivot(max(分數)for課程in(語文,數學,物理))a

三、

UNPIVOT用於將列明轉為列值(即列轉行),在SQL Server 2000可以用UNION來實現

完整語法:

table_source        --數據源 轉化后的表結構查詢  例如:select 姓名,課程,分數 from tb1

UNPIVOT(

value_column         --列值(本身列名的值 如:語文 列  值 83 ) 例如:分數

FOR pivot_column   --列名 (集合列轉成行后的名字 例如:課程)

IN(<column_list>)   --集合參數 (例如:[語文],[數學],[物理])

)

 示例:

create table tb(姓名varchar(10),語文int,數學int,物理int)

insert into tb values('張三',74,83,93)

insert into tb values('李四',74,84,94)

go

select  *from tb

go

姓名       語文        數學        物理

---------- ----------- ----------- -----------

張三       74          83          93

李四        74          84          94

 

2、使用SQL Server 2000靜態SQL

--SQL SERVER 2000靜態SQL。

select*from

(

 select 姓名,課程='語文',分數=語文 from tb

 union all

 select姓名,課程='數學',分數=數學 from tb

 union all

 select姓名,課程='物理',分數=物理 from tb

) t

order b y 姓名,case 課程 when '語文' then 1 when '數學' then 2 when '物理' then 3 end

姓名       課程 分數

---------- ---- -----------

李四       語文 74

李四       數學 84

李四       物理 94

張三       語文 74

張三       數學 83

張三       物理 93
2、使用SQL Server 2005靜態SQL

--SQL SERVER 2005動態SQL

select 姓名,課程,分數 from tb unpivot ( 分數 for 課程 in([語文],[數學],[物理])) t

 

 四、 merge 用於2張表更新的常用關鍵字

基本語法:

MERGE  table         --要匹配的目標表 a
using scourtb --查詢的源數據或者元數據表名 b
on conditaion --元數據與目標表的匹配條件
when matched then --匹配成功 update set a.字段=X --一般匹配成功都是執行更新
when not matched then --匹配不成功 insert (A字段) values (對應的值);  --執行插入 向目標表插入元數據的新數據
WHEN NOT MATCHED BY SOURCE THEN DELETE; -- 目標表有,源表沒有,目標表該數據刪除.
示例:
create table employee
(
empid integer,
fname nvarchar(20),
lname nvarchar(20)
)
insert into employee
select 2021110,'',''
 
insert into employee
select 2021110,'',''
 
 
create table test
(
id integer,
num integer
)
 
insert into test
select 2021110,2
 
insert into test
select 2,2
 
 
期望結果語句:select * from  employee
2021110,'',''
2021110,'',''
2,'',''

SQL語句實現:

merge into  employee a
   using  test b
   on   b.id = a.empid 
   when matched then
     update set a.fname= ''
   when not matched then
   insert values (id,'',''); 
 end
  
 exec test_merge
select * from employee
 
/*
empid       fname                lname
----------- -------------------- --------------------
2021110     大                    張
2021110     大                    李
2           大                    大
 
(3 行受影響)

 五、sql STUFF用法

1、作用

刪除指定長度的字符,並在指定的起點處插入另一組字符。

2、語法

STUFF ( character_expression , start , length ,character_expression )

3、示例

以下示例在第一個字符串 abcdef 中刪除從第 2 個位置(字符 b)開始的三個字符,然后在刪除的起始位置插入第二個字符串,從而創建並返回一個字符串

SELECT STUFF('abcdef', 2, 3, 'ijklmn')
GO

下面是結果集

aijklmnef

4、參數
character_expression

一個字符數據表達式。character_expression 可以是常量、變量,也可以是字符列或二進制數據列。

start

一個整數值,指定刪除和插入的開始位置。如果 start 或 length 為負,則返回空字符串。如果 start 比第一個 character_expression長,則返回空字符串。start 可以是 bigint 類型。

length

一個整數,指定要刪除的字符數。如果 length 比第一個 character_expression長,則最多刪除到最后一個 character_expression 中的最后一個字符。length 可以是 bigint 類型。

5、返回類型
如果 character_expression 是受支持的字符數據類型,則返回字符數據。如果 character_expression 是一個受支持的 binary 數據類型,則返回二進制數據。

6、備注
如果結果值大於返回類型支持的最大值,則產生錯誤。

六、sql for xml path用法

 

 一.FOR XML PATH 簡單介紹

 

             那么還是首先來介紹一下FOR XML PATH ,假設現在有一張興趣愛好表(hobby)用來存放興趣愛好,表結構如下:

 

       接下來我們來看應用FOR XML PATH的查詢結果語句如下:

 

SELECT   *   FROM   @hobby   FOR  XML PATH

 

       結果:

 

復制代碼
復制代碼
< row >
  
< hobbyID > 1 </ hobbyID >
  
< hName > 爬山 </ hName >
</ row >
< row >
  
< hobbyID > 2 </ hobbyID >
  
< hName > 游泳 </ hName >
</ row >
< row >
  
< hobbyID > 3 </ hobbyID >
  
< hName > 美食 </ hName >
</ row >
復制代碼
復制代碼

 

      由此可見FOR XML PATH 可以將查詢結果根據行輸出成XML各式!

 

      那么,如何改變XML行節點的名稱呢?代碼如下:     

 

SELECT   *   FROM   @hobby   FOR  XML PATH( ' MyHobby ' )

 

 

 

      結果一定也可想而知了吧?沒錯原來的行節點<row> 變成了我們在PATH后面括號()中,自定義的名稱<MyHobby>,結果如下:

 

復制代碼
復制代碼
< MyHobby >
  
< hobbyID > 1 </ hobbyID >
  
< hName > 爬山 </ hName >
</ MyHobby >
< MyHobby >
  
< hobbyID > 2 </ hobbyID >
  
< hName > 游泳 </ hName >
</ MyHobby >
< MyHobby >
  
< hobbyID > 3 </ hobbyID >
  
< hName > 美食 </ hName >
</ MyHobby >
復制代碼
復制代碼

 

      這個時候細心的朋友一定又會問那么列節點如何改變呢?還記的給列起別名的關鍵字AS嗎?對了就是用它!代碼如下:

 

SELECT  hobbyID  as   ' MyCode ' ,hName  as   ' MyName '   FROM   @hobby   FOR  XML PATH( ' MyHobby ' )

 

 

      那么這個時候我們列的節點名稱也會編程我們自定義的名稱 <MyCode>與<MyName>結果如下:

復制代碼
復制代碼
< MyHobby >
  
< MyCode > 1 </ MyCode >
  
< MyName > 爬山 </ MyName >
</ MyHobby >
< MyHobby >
  
< MyCode > 2 </ MyCode >
  
< MyName > 游泳 </ MyName >
</ MyHobby >
< MyHobby >
  
< MyCode > 3 </ MyCode >
  
< MyName > 美食 </ MyName >
</ MyHobby >
復制代碼
復制代碼

    噢! 既然行的節點與列的節點我們都可以自定義,我們是否可以構建我們喜歡的輸出方式呢?還是看代碼: 

SELECT   ' ' + hName + '  ] '   FROM   @hobby   FOR  XML PATH( '' )

 

    沒錯我們還可以通過符號+號,來對字符串類型字段的輸出格式進行定義。結果如下:

 

[ 爬山 ][ 游泳 ][ 美食 ]

 

    那么其他類型的列怎么自定義? 沒關系,我們將它們轉換成字符串類型就行啦!例如:

 

SELECT   ' { ' + STR (hobbyID) + ' } ' , ' ' + hName + '  ] '   FROM   @hobby   FOR  XML PATH( '' )

 

    好的 FOR XML PATH就基本介紹到這里吧,更多關於FOR XML的知識請查閱幫助文檔!

 

    接下來我們來看一個FOR XML PATH的應用場景吧!那么開始吧。。。。。。

 

        二.一個應用場景與FOR XML PATH應用

 

        首先呢!我們在增加一張學生表,列分別為(stuID,sName,hobby),stuID代表學生編號,sName代表學生姓名,hobby列存學生的愛好!那么現在表結構如下:

 

           

 

        這時,我們的要求是查詢學生表,顯示所有學生的愛好的結果集,代碼如下:

 

復制代碼
復制代碼
SELECT  B.sName, LEFT (StuList, LEN (StuList) - 1 as  hobby  FROM  (
SELECT  sName,
(
SELECT  hobby + ' , '   FROM  student 
  
WHERE  sName = A.sName 
  
FOR  XML PATH( '' ))  AS  StuList
FROM  student A 
GROUP   BY  sName
) B 
復制代碼
復制代碼

 

         結果如下:

 

 分析: 好的,那么我們來分析一下,首先看這句:

 

SELECT  hobby + ' , '   FROM  student 
  
WHERE  sName = A.sName 
  
FOR  XML PATH( '' )

 

這句是通過FOR XML PATH 將某一姓名如張三的愛好,顯示成格式為:“ 愛好1,愛好2,愛好3,”的格式!

 

那么接着看:

 

復制代碼
復制代碼
SELECT  B.sName, LEFT (StuList, LEN (StuList) - 1 as  hobby  FROM  (
SELECT  sName,
(
SELECT  hobby + ' , '   FROM  student 
  
WHERE  sName = A.sName 
  
FOR  XML PATH( '' ))  AS  StuList
FROM  student A 
GROUP   BY  sName
) B  
復制代碼
復制代碼

 

剩下的代碼首先是將表分組,在執行FOR XML PATH 格式化,這時當還沒有執行最外層的SELECT時查詢出的結構為:

 

 

可以看到StuList列里面的數據都會多出一個逗號,這時隨外層的語句:SELECT B.sName,LEFT(StuList,LEN(StuList)-1as hobby  就是來去掉逗號,並賦予有意義的列明!

也可以這樣寫:

select NAME,
STUFF((select ','+fv+'' from #TEMP tb1 where tb1.name=tb.name for xml path('')),1,1,'') as fv   --截取查詢的結果集合,替換第一個字符
from #TEMP as tb group by tb.NAME

三、關於主從表關聯取從表最大數據一條記錄問題

select a.*,b.* FROM dbo.SQ_AJBL AS a
left join SQ_AJBLWorkFlow AS b on a.gID=b.gPID
where b.dCreateDate IN (select max(dCreateDate) from SQ_AJBLWorkFlow GROUP BY gPID)


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM