T-SQL執行順序

來源:互聯網
上載者:User

T-SQL是需要最佳化的。而最佳化的前提是你對它的執行步驟有清楚的認識。我經常去給講課或者諮詢輔導的時候,就發現很多朋友對此瞭解甚少。下面截取了我的一個PPT,給大家參考一下

下面這個指令碼可以解釋這個過程

/*
這個指令碼用來協助使用者理解T-SQL查詢的邏輯順序和原理。
作者:陳希章
*/

/*
準備資料架構和資料
*/
SET NOCOUNT ON;
USE tempdb;
GO
IF OBJECT_ID('dbo.Orders') IS NOT NULL
  DROP TABLE dbo.Orders;
GO
IF OBJECT_ID('dbo.Customers') IS NOT NULL
  DROP TABLE dbo.Customers;
GO
CREATE TABLE dbo.Customers
(
  customerid  CHAR(5)     NOT NULL PRIMARY KEY,
  city        VARCHAR(10) NOT NULL
);

INSERT INTO dbo.Customers(customerid, city) VALUES('FISSA', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('FRNDO', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('KRLOS', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('MRPHS', 'Zion');

CREATE TABLE dbo.Orders
(
  orderid    INT        NOT NULL PRIMARY KEY,
  customerid CHAR(5)    NULL     REFERENCES Customers(customerid)
);

INSERT INTO dbo.Orders(orderid, customerid) VALUES(1, 'FRNDO');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(2, 'FRNDO');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(3, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(4, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(5, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(6, 'MRPHS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(7, NULL);

/*
一個測試查詢,檢索那些訂單個數小於3的客戶,並且按訂單總數排序(升序)
*/
SELECT C.customerid, COUNT(O.orderid) AS numorders
FROM dbo.Customers AS C
  LEFT OUTER JOIN dbo.Orders AS O
    ON C.customerid = O.customerid
WHERE C.city = 'Madrid'
GROUP BY C.customerid
HAVING COUNT(O.orderid) < 3
ORDER BY numorders;

/*第一步:處理FROM子句,把來源的表進行CROSS JOIN(笛卡爾乘積)
我這裡把結果做一個產生資料表查詢,寫到一個暫存資料表(VT1)中去
*/
SELECT C.customerid as Customer,c.city,o.*  INTO #VT1 FROM dbo.Customers C,dbo.Orders  O
SELECT * FROM #VT1
--返回28行資料(4*7)

--第二步:處理ON子句,只把那些兩個表的customerid匹配的行找出來,我把它們放到VT2中去
SELECT temp.* INTO #VT2 FROM (SELECT * FROM #VT1 WHERE Customer=customerid) temp
SELECT * FROM #VT2
--返回6行資料

--第三步:根據JOIN語句的類型,決定是否要添加行到VT2中去,例如如果是LEFT  JOIN的話,那麼就要檢查坐邊的表(我們這裡是customers表)的串連索引值是否都存在,如果不存在就要去添加到VT2中
SELECT temp.* INTO #VT3 FROM
(SELECT * FROM #VT2
UNION ALL
SELECT CustomerID,City,NULL,NULL FROM dbo.Customers c WHERE NOT EXISTS(SELECT DISTINCT Customer FROM #VT2 WHERE Customer=c.CustomerID)) temp
SELECT * FROM #VT3
--返回7行資料,其中有一個客戶,因為沒有訂單,這一步中被添加進來。它的Orders的記錄被標記為NULL

--第四步:處理WHERE 子句,對VT3的結果集進行過濾,我們的條件是city=Madid
SELECT temp.* INTO #VT4 FROM
(SELECT * FROM #VT3 WHERE city='Madrid') temp
SELECT * FROM #VT4
--返回6行資料,因為有一個客戶不是這個城市的

--第五步:處理GROUP子句,進行分類匯總
SELECT temp.* INTO #VT5 FROM
(SELECT Customer,COUNT(OrderID)  as orderidcount,COUNT(city) as citycount,Count(customerid)  as customeridcount FROM #VT4 GROUP BY Customer) temp
SELECT * FROM #VT5
--返回3行資料,根據客戶分組,統計了訂單的個數
--這裡會不會去統計其他列的匯總呢

--因為沒有WITH Rollup和WITH Cube語句,所以跳過第六步,進入HAVING子句的處理

--第六步:處理HAVING子句,對GROUP之後的結果進行篩選,我們這裡的條件是orderidcount<3
SELECT temp.* INTO #VT6 FROM
(SELECT * FROM #VT5 WHERE orderidcount<3) temp
SELECT * FROM #VT6
--返回2行資料

--第七步:使用SELECT 的欄位列表過濾結果集
SELECT #VT6.Customer,#VT6.orderidcount as  numorders  INTO #VT7 FROM #VT6
SELECT * FROM #VT7
--還是2行資料,只不過只有兩個列了

--第八步:跳過DISTINCT,進行OrderBy操作
SELECT #VT7.* INTO #VT8 FROM #VT7 Order By #VT7.Customer
SELECT * FROM #VT8
--返回2行資料,經過排序

--這個查詢結束示範。完整的8個步驟

     轉至:http://www.cnblogs.com/chenxizhang/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.