Tom Moreau Translated by mschen T-SQL允許你使用不同的方法解決一個問題.有的時候,盡" name="description" />

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Performance Through Persistence

    發表于:2007-05-25來源:作者:點擊數: 標簽:ThroughPersistencperformance
    MI LY: Verdana; mso-fareast-font-family: 宋體; mso-bidi-font-family: 宋體; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"> Tom Moreau Translated by mschen T-SQL允許你使用不同的方法解決一個問題.有的時候,盡

    MILY: Verdana; mso-fareast-font-family: 宋體; mso-bidi-font-family: 宋體; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Tom Moreau

    Translated by mschen

    T-SQL允許你使用不同的方法解決一個問題.有的時候,盡管選擇不是那么明顯,但是卻可以讓你得到令人滿意的和快樂的驚奇.下邊讓我們解讀Dr. Tom Moreau對同一問題不同的可能性的探索.可能我們可以在那些不同的方法之中發現一些珍貴的東西.

      讓我們以我們的老朋友Northwind數據庫為例,這里我們用到的是[order details]表,這個表是一個定單的明細表,和order表是多對一的關系.也就是一個定單對應多個訂購的產品.假設你想得到每個定單訂購的總價值,但是不包括59號產品.Listing 1給了我們第一種解法:

    select
      OrderID,sum (Quantity * UnitPrice) value
    from
      [Order Details] o1
    where
      ProductID <> 59
    group by
      OrderID

    上邊的語句很簡單,它排除掉了59號產品的定單明細條目,然后進行分組統計.但是如果我們需要忽略掉訂購59號產品的定單呢?也就是說我們要統計沒有包含59號產品的定單的價值.你想到了WHERE, NOT EXIST(S)關鍵詞了嗎?Listing 2給了我們第二種方法:

    select
      o1.OrderID,sum (o1.Quantity * o1.UnitPrice) value
    from
      [Order Details] o1
    where not exists
    (
      select
        *
      from
        [Order Details] o2
      where
        o2.OrderID   = o1.OrderID
      and o2.ProductID = 59
    )
    group by
      o1.OrderID

    如果你不喜歡用exist的話,你可以轉化成使用not in:
    Listing 3

    select
      o1.OrderID,sum (o1.Quantity * o1.UnitPrice) value
    from
      [Order Details] o1
    where 59 not in
    (
      select
        ProductID
      from
        [Order Details] o2
      where
        o2.OrderID   = o1.OrderID
    )
    group by
      o1.OrderID

    盡管Listing 1不滿足我們現在的查詢條件.但是從性能發面考慮,Listing 1還是最好的,因為它只用到了一次表的掃描.而后邊的兩個查詢都是用到了相關子查詢,如果你查看查詢計劃就回看到,他們都涉及到了兩次表的掃描.如果你曾經在 T-SQL用過交叉表查詢的話,你就不會對聚集函數里邊的case結構陌生.現在我們就把這個非常有趣的方法應用到我們的問題中來:
    Listing 4

    select
      OrderID,sum (Quantity * UnitPrice) value
    from
      [Order Details] o1
    group by
      OrderID
    having
      sum (case when ProductID = 59 then 1 else 0 end) = 0

    HAVING子句起到了對分組的結果進行過濾的作用.如果沒有包含59號產品,就會出現0=0,顯然這是滿足條件的.如果包含了59號產品的訂購,就會出現n=0(n<>0),這樣的定單就回被過濾掉.查看執行計劃你就回發現是一次表的掃描,非常棒!
      再來舉一個例子:我們這回用到的表是order表,假設我們要統計只通過一個雇員雇員下定單的顧客.你可以想到用子查詢not exist來實現:

    select distinct
      o1.CustomerID
    from
      Orders o1
    where not exists
    (
      select
        *
      from
        Orders o2
        where
          o2.CustomerID = o1.CustomerID
        and o2.EmployeeID <> o1.EmployeeID
    )

    同樣的,這個語句可以通過帶有HAVING子句的分組來實現.
    Listing 6

    select
      CustomerID
    from
      Orders
    group by
      CustomerID
    having
      min (EmployeeID) = max (EmployeeID)

    另一種方法:
    Listing 7

    select
    CustomerID
    from
      Orders
    group by
      CustomerID
    having
      count (distinct EmployeeID) = 1

    Listing 6和Listing 7查詢消耗都要小于Listing 5.相比Listing 5的兩次表掃描,他們只進行一次表的掃描.而Listing 6的損耗還要稍微小于Listing 7.但是,Listing 7的一個顯著的特點就是它可以適應到一個顧客對應兩個雇員,三個雇員......
    其實大家可能現在明白了這篇文章將的是什么?它就是教我們怎么用having 子句來達到過濾組的目的.可以達到避免兩次表掃描的目的.可以達到更高的性能.我從這篇文章學到了很多的方法,你呢?


    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>