sql apply查詢應用

相關博客:html

SQL中ROW_NUMBER和APPLY在處理TOP N等相似問題的一點比較服務器

SQL Server-聚焦APPLY運算符(二十七)app

你真的會玩SQL嗎?冷落的Top和Applyide

有如下應用場景函數

  • 當用到了row_number over作分組排序時,能夠考慮用apply...top替換

row_number over語句:大數據

SELECT A.*
  FROM (   SELECT ROW_NUMBER() OVER (PARTITION BY O.employeeID ORDER BY O.orderdate DESC) AS ROW,
                  E.LastName,
                  E.FirstName,
                  O.*
             FROM Employees E
             JOIN Orders O
               ON E.EmployeeID = O.EmployeeID) A
 WHERE A.ROW <= 2
 ORDER BY A.EmployeeID;

這裏是,先按employeeID分組再組內又按orderdate排序。用apply...top替換ui

SELECT       E.FirstName,
             E.LastName,
             OT.*
  FROM       Employees E
 CROSS APPLY (   SELECT TOP (2) *
                   FROM Orders O
                  WHERE O.EmployeeID = E.EmployeeID
                  ORDER BY O.OrderDate DESC) AS OT
 ORDER BY E.EmployeeID;

能夠用 EXCEPT 比較下兩個查詢語句得差別。若是沒有輸出,那麼說明徹底是等價的。調試

當能夠只須要輸出一個聚合函數得值時,直接搞。例子以下:code

SELECT 
    soh.SalesOrderID
    ,soh.OrderDate
    ,sod.max_unit_price
FROM Sales.SalesOrderHeader AS soh
JOIN
(
    SELECT 
        max_unit_price = MAX(sod.UnitPrice),
        SalesOrderID
    FROM Sales.SalesOrderDetail AS sod
    GROUP BY sod.SalesOrderID
) sod
ON sod.SalesOrderID = soh.SalesOrderID

這裏是關聯查詢了另一張表 SalesOrderDetail,須要查出對應的UnitPrice得最大值。用apply...聚合函數直接替換。htm

SELECT 
    soh.SalesOrderID
    ,soh.OrderDate
    ,sod.max_unit_price
FROM Sales.SalesOrderHeader AS soh
CROSS APPLY
(
    SELECT 
        max_unit_price = MAX(sod.UnitPrice)
    FROM Sales.SalesOrderDetail AS sod
    WHERE soh.SalesOrderID = sod.SalesOrderID
) sod

那若是不是呢。

SELECT /*主外鍵*/
                       DISTINCT    sale.WideGUID AS WideGUID, --業務GUID,
                                   s_room.RoomNo,
                                   s_room.Room AS RoomNum,
                                   s_room.UnitNo,
                                   s_room.FloorNo,
                                   s_room.HxName AS HxName, --戶型
                                   s_room.RoomStru AS RoomType, --房間類型
                                   s_room.Unit AS Unit, --單元
                                   s_room.FloorName AS Floor, --樓層·
                                   s_room.No AS No, --號碼
                                   s_room.RoomInfo AS RoomInfo, --房間全稱
                                   s_room.XxDate AS XxDate, --銷許日期
                                   s_room.JFDate AS SjjfDate, --實際交房日期
                                   s_room.ShortRoomInfo AS ShortRoomInfo, --房間簡稱
                                   s_room.FangPanUser AS FangPanUser, --放盤人
                                   s_room.FangPanTime AS FangPanTime, --放盤時間
                                   RoomControl.Reason AS FangPanReason --放盤批次
             FROM      (   SELECT DISTINCT s.WideGUID,
                                           s.RoomGUID
                             FROM (   SELECT WideGUID,
                                             RoomGUID
                                        FROM s_Order
                                       WHERE OrderTypeEnum = 0
                                      UNION ALL
                                      SELECT WideGUID,
                                             RoomGuid
                                        FROM s_Contract) s ) sale
             LEFT JOIN s_room
               ON s_room.RoomGUID      = sale.RoomGUID
             LEFT JOIN (   SELECT      s_RoomControl.RoomGUID,
                                       Reason
                             FROM      s_RoomControl
                            INNER JOIN (   SELECT RoomGUID,
                                                  MAX(ControlTime) ControlTime
                                             FROM s_RoomControl
                                            WHERE ControlType = 0
                                            GROUP BY RoomGUID) T
                               ON T.RoomGUID    = s_RoomControl.RoomGUID
                              AND T.ControlTime = s_RoomControl.ControlTime) RoomControl
               ON RoomControl.RoomGUID = s_room.RoomGUID

替換爲:

SELECT /*主外鍵*/
                        sale.WideGUID AS WideGUID, --業務GUID,
                        s_room.RoomNo,
                        s_room.Room AS RoomNum,
                        s_room.UnitNo,
                        s_room.FloorNo,
                        s_room.HxName AS HxName, --戶型
                        s_room.RoomStru AS RoomType, --房間類型
                        s_room.Unit AS Unit, --單元
                        s_room.FloorName AS Floor, --樓層·
                        s_room.No AS No, --號碼
                        s_room.RoomInfo AS RoomInfo, --房間全稱
                        s_room.XxDate AS XxDate, --銷許日期
                        s_room.JFDate AS SjjfDate, --實際交房日期
                        s_room.ShortRoomInfo AS ShortRoomInfo, --房間簡稱
                        s_room.FangPanUser AS FangPanUser, --放盤人
                        s_room.FangPanTime AS FangPanTime, --放盤時間
                        RoomControl.Reason AS FangPanReason --放盤批次
             FROM       (   SELECT DISTINCT s.WideGUID,
                                            s.RoomGUID
                              FROM (   SELECT WideGUID,
                                              RoomGUID
                                         FROM s_Order
                                        WHERE OrderTypeEnum = 0
                                       UNION ALL
                                       SELECT WideGUID,
                                              RoomGuid
                                         FROM s_Contract) s ) sale
             LEFT JOIN  s_room
               ON s_room.RoomGUID = sale.RoomGUID
            CROSS APPLY (   SELECT TOP 1 Reason
                              FROM dbo.s_RoomControl
                             WHERE dbo.s_RoomControl.RoomGUID = dbo.s_room.RoomGUID
                               AND ControlType                = 0
                             ORDER BY ControlTime DESC) RoomControl

爲何會分析apply呢,主要是近期在工做中遇到大數據量狀況下的分頁查詢,以及聚合查詢,表的數據量原本就大,再這麼一通操做,服務器直接扛不住。經過實踐調試,最後發現apply能夠解決這個問題,可是網上對這個apply也沒過多的講述,在這裏也只是作個總結。最後的建議是,若是在大數據量下有分頁查詢或是鏈接大表又須要聚合查詢,能夠嘗試apply得寫法。能夠用except來驗證二者的輸出。

相關文章
相關標籤/搜索