SQL語句使用總結(一)

weixin_34344677發表於2012-09-08

 SELECT語句執行的過程是:

1>. FROM
2>. WHERE
3>. GROUP BY
4>. HAVING
5>. SELECT
6>. ORDER BY

WHERE子句在SELECT子句之前執行,所以在SELECT中的列別名,WHERE中當然是不會認識的。

 

Order by和Top語句一起的時候,執行的順序就不同了。先order by 進行排序,然後在取Top前X條記錄。

eg:SELECT TOP 10000 * FROM OrderDetail
ORDER BY OrderDetailID DESC
上面語句是取OrderDetail表中的最後1W條記錄。

 

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

一.FOR XML PATH 簡單介紹

FOR XML PATH 有的人可能知道有的人可能不知道,其實它就是將查詢結果集以XML形式展現,有了它我們可以簡化我們的查詢語句實現一些以前可能需要藉助函式活儲存過程來完成的工作。那麼以一個例項為主。

 使用FOR XML PATH('')),1,1,'')語句。

例如表
fieldname
-----------
AAA
BBB
CCC
串聯之後就是字串: AAA,BBB,CCC

 

 

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

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

          

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

 

SELECT B.sName,LEFT(StuList,LEN(StuList)-1as 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,”的格式!

那麼接著看:

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

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

 

二、with (nolock)的介紹和使用。

 

為了效能,往往會在表後面加一個nolock,或者是with(nolock),其目的就是查詢是不鎖定表,從而達到提高查詢速度的目的。

什麼是併發訪問:同一時間有多個使用者訪問同一資源,併發使用者中如果有使用者對資源做了修改,此時就會對其它使用者產生某些不利的影響,例如:

1:髒讀,一個使用者對一個資源做了修改,此時另外一個使用者正好讀取了這條被修改的記錄,然後,第一個使用者放棄修改,資料回到修改之前,這兩個不同的結果就是髒讀。(即B使用者讀取了一個A使用者沒有提交事務的資料(rollback transaction),這樣讀出來的資料是屬於髒資料)

 

小結:NOLOCK 語句執行時不發出共享鎖,允許髒讀 ,等於 READ UNCOMMITTED事務隔離級別
nolock確實在查詢時能提高速度,但它並不是沒有缺點的,起碼它會引起髒讀。


 

nolock的使用場景(個人觀點):

NOLOCK 可能把沒有提交事務的資料也顯示出來.

1:資料量特別大的表,犧牲資料安全性來提升效能是可以考慮的;

2:允許出現髒讀現象的業務邏輯,反之一些資料完整性要求比較嚴格的場景就不合適了,像金融方面等。

3:資料不經常修改的表,這樣會省於鎖定表的時間來大大加快查詢速度。


綜上所述,如果在專案中的每個查詢的表後面都加nolock,這種做法並不科學,起碼特別費時間,不如行版本控制來的直接有效。而且會存在不可預期的技術問題。應該有選擇性的挑選最適合的表來放棄共享鎖的使用。


最後說下nolockwith(nolock)的幾個小區別:

1:SQL05中的同義詞,只支援with(nolock);

2:with(nolock)的寫法非常容易再指定索引。

跨伺服器查詢語句時 不能用with (nolock)
只能用nolock
同一個伺服器查詢時
with (nolock)和nolock都可以用
比如

 

SQL code

select * from [IP].a.dbo.table1 with
(nolock) 這樣會提示用錯誤select * from a.dbo.table1
with (nolock) 這樣就可以

 

 三、資料表死鎖

如果對某一個進行了事務操作,如果該操作最後完成沒有提交事務或者回滾事務。則表差生死鎖狀態。

例如:

BEGIN TRANSACTION

insert into tableA values(。。。。)

此時沒有Commit transaction或者Rollback transaction操作,則tableA將被死鎖。

 

四、Output和Output into 語句的使用。

參考CSDN資料:http://msdn.microsoft.com/zh-cn/library/ms177564(SQL.105).aspx#

 

A. 將 OUTPUT INTO 用於簡單 INSERT 語句

   以下示例將行插入soloreztest表,並使用 OUTPUT 子句將語句的結果返回到 @mytable table 變數中
declare @mytable table
(
  id int identity(1,1) primary key,
  name varchar(50)
)
insert into soloreztest output inserted.name into @mytable values('147')
select * from soloreztest
select * from @mytable

結果是:
 

  output    into子句是將向soloreztest表裡面的資料同步的插入的@mytable的表變數裡面
  output 子句則只是用於顯示被改變的資料INSERTED 或 DELETED 字首
  inserted 字首:用於檢索新插入表中或是更新後的資料的資料 可用與insert和update語句中不能在delete語句中出現
  deleted 字首: 用於檢索被刪除或是更新前的資料 可用與delete和update語句中不能在insert 語句中出現

B. 將 OUTPUT 用於 DELETE 語句
   以下例項是將在表中soloreztest刪除行是放回被刪除行的資訊
     delete soloreztest  output deleted.* where id=2
  

 

同理以上也可使用會 output into語句將被刪除的資訊插入到一個新表中


C. 將 OUTPUT  用於 UPDATE
以下例項將在表中更新資料是使用output 返回修改前的資料和修改後的資料
update soloreztest   set name='zz' output  inserted.name,deleted.name where id=3

inserted.name:表示的是在 soloreztest表中更新後的資料內容。
deleted.name :表示的是在soloreztest表中的更新前的資料內容。

 

四、with as 語句

 參考文章:http://www.cnblogs.com/fygh/archive/2011/08/31/2160266.html

 

好處:

1) WITH AS儲存過程中使用,宣告瞭就一定要用,不然會報錯.

2) 儲存過程中如果有select 好像就一定得有into......

3) 複雜的查詢會產生很大的sql,with as語法顯示一個個中間結果,顯得有條理些,可讀性提高

4) 前面的中間結果可以被語句中的select或後面的中間結果表引用,類似於一個範圍僅限於本語句的臨時表,在需要多次查詢某中間結果時可以提升效率

例子:
with t as (select * from emp where depno=10)
select * from t where empno=xxx

再舉個簡單的例子

with a as (select * from test)

select * from a;

其實就是把一大堆重複用到的SQL語句放在with as 裡面,取一個別名,後面的查詢就可以用它

這樣對於大批量的SQL語句起到一個優化的作用,而且清楚明瞭

是個臨時儲存,一般是在儲存過程裡使用的

可以做多個表的連線,結果集的連線查詢

 

 

相關文章