亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        SQL語(yǔ)句:GroupBy總結(jié)

        字號(hào):

        1. Group By 語(yǔ)句簡(jiǎn)介:
            Group By語(yǔ)句從英文的字面意義上理解就是“根據(jù)(by)一定的規(guī)則進(jìn)行分組(Group)”。它的作用是通過(guò)一定的規(guī)則將一個(gè)數(shù)據(jù)集劃分成若干個(gè)小的區(qū)域,然后針對(duì)若干個(gè)小區(qū)域進(jìn)行數(shù)據(jù)處理。
            P.S. 這里真是體會(huì)到了一個(gè)好的命名的力量,Group By從字面是直接去理解是非常好理解的。恩,以后在命名的環(huán)節(jié)一定要加把勁:)。話題扯遠(yuǎn)了。
            2. Group By 的使用:
            上面已經(jīng)給出了對(duì)Group By語(yǔ)句的理解?;谶@個(gè)理解和SQL Server 2000的聯(lián)機(jī)幫助,下面對(duì)Group By語(yǔ)句的各種典型使用進(jìn)行依次列舉說(shuō)明。
            2.1 Group By [Expressions]:
            這個(gè)恐怕是Group By語(yǔ)句最常見的用法了,Group By + [分組字段](可以有多個(gè))。在執(zhí)行了這個(gè)操作以后,數(shù)據(jù)集將根據(jù)分組字段的值將一個(gè)數(shù)據(jù)集劃分成各個(gè)不同的小組。比如有如下數(shù)據(jù)集,其中水果名稱(FruitName)和出產(chǎn)國(guó)家(ProductPlace)為聯(lián)合主鍵:
            FruitNameProductPlacePrice
            AppleChina$1.1
            AppleJapan$2.1
            AppleUSA$2.5
            OrangeChina$0.8
            BananaChina$3.1
            PeachUSA$3.0
            如果我們想知道每個(gè)國(guó)家有多少種水果,那么我們可以通過(guò)如下SQL語(yǔ)句來(lái)完成:
            SELECT COUNT(*) AS 水果種類, ProductPlace AS 出產(chǎn)國(guó)
            FROM T_TEST_FRUITINFO
            GROUP BY ProductPlace
            這個(gè)SQL語(yǔ)句就是使用了Group By + 分組字段的方式,那么這句SQL語(yǔ)句就可以解釋成“我按照出產(chǎn)國(guó)家(ProductPlace)將數(shù)據(jù)集進(jìn)行分組,然后分別按照各個(gè)組來(lái)統(tǒng)計(jì)各自的記錄數(shù)量?!焙芎美斫鈱?duì)吧。這里值得注意的是結(jié)果集中有兩個(gè)返回字段,一個(gè)是ProductPlace(出產(chǎn)國(guó)), 一個(gè)是水果種類。如果我們這里水果種類不是用Count(*),而是類似如下寫法的話:
            SELECT FruitName, ProductPlace FROM T_TEST_FRUITINFO GROUP BY ProductPlace
            那么SQL在執(zhí)行此語(yǔ)句的時(shí)候會(huì)報(bào)如下的類似錯(cuò)誤:
            選擇列表中的列 ’T_TEST_FRUITINFO.FruitName’ 無(wú)效,因?yàn)樵摿袥](méi)有包含在聚合函數(shù)或 GROUP BY 子句中。
            這就是我們需要注意的一點(diǎn),如果在返回集字段中,這些字段要么就要包含在Group By語(yǔ)句的后面,作為分組的依據(jù);要么就要被包含在聚合函數(shù)中。我們可以將Group By操作想象成如下的一個(gè)過(guò)程,首先系統(tǒng)根據(jù)SELECT 語(yǔ)句得到一個(gè)結(jié)果集,如最開始的那個(gè)水果、出產(chǎn)國(guó)家、單價(jià)的一個(gè)詳細(xì)表。然后根據(jù)分組字段,將具有相同分組字段的記錄歸并成了一條記錄。這個(gè)時(shí)候剩下的那些不存在于Group By語(yǔ)句后面作為分組依據(jù)的字段就有可能出現(xiàn)多個(gè)值,但是目前一種分組情況只有一條記錄,一個(gè)數(shù)據(jù)格是無(wú)法放入多個(gè)數(shù)值的,所以這里就需要通過(guò)一定的處理將這些多值的列轉(zhuǎn)化成單值,然后將其放在對(duì)應(yīng)的數(shù)據(jù)格中,那么完成這個(gè)步驟的就是聚合函數(shù)。這就是為什么這些函數(shù)叫聚合函數(shù)(aggregate functions)了。
            2.2 Group By All [expressions] :
            Group By All + 分組字段, 這個(gè)和前面提到的Group By [Expressions]的形式多了一個(gè)關(guān)鍵字ALL。這個(gè)關(guān)鍵字只有在使用了where語(yǔ)句的,且where條件篩選掉了一些組的情況才可以看出效果。在SQL Server 2000的聯(lián)機(jī)幫助中,對(duì)于Group By All是這樣進(jìn)行描述的:
            如果使用 ALL 關(guān)鍵字,那么查詢結(jié)果將包括由 GROUP BY 子句產(chǎn)生的所有組,即使某些組沒(méi)有符合搜索條件的行。沒(méi)有 ALL 關(guān)鍵字,包含 GROUP BY 子句的 SELECT 語(yǔ)句將不顯示沒(méi)有符合條件的行的組。
            其中有這么一句話“如果使用ALL關(guān)鍵字,那么查詢結(jié)果將包含由Group By子句產(chǎn)生的所有組...沒(méi)有ALL關(guān)鍵字,那么不顯示不符合條件的行組?!边@句話聽起來(lái)好像挺耳熟的,對(duì)了,好像和LEFT JOIN 和 RIGHT JOIN 有點(diǎn)像。其實(shí)這里是類比LEFT JOIN來(lái)進(jìn)行理解的。還是基于如下這樣一個(gè)數(shù)據(jù)集:
            FruitNameProductPlacePrice
            AppleChina$1.1
            AppleJapan$2.1
            AppleUSA$2.5
            OrangeChina$0.8
            BananaChina$3.1
            PeachUSA$3.0
            首先我們不使用帶ALL關(guān)鍵字的Group By語(yǔ)句:
            SELECT COUNT(*) AS 水果種類, ProductPlace AS 出產(chǎn)國(guó)
            FROM T_TEST_FRUITINFO
            WHERE (ProductPlace <> ’Japan’)
            GROUP BY ProductPlace
            那么在最后結(jié)果中由于Japan不符合where語(yǔ)句,所以分組結(jié)果中將不會(huì)出現(xiàn)Japan。
            現(xiàn)在我們加入ALL關(guān)鍵字:
            SELECT COUNT(*) AS 水果種類, ProductPlace AS 出產(chǎn)國(guó)
            FROM T_TEST_FRUITINFO
            WHERE (ProductPlace <> ’Japan’)
            GROUP BY ALL ProductPlace
            重新運(yùn)行后,我們可以看到Japan的分組,但是對(duì)應(yīng)的“水果種類”不會(huì)進(jìn)行真正的統(tǒng)計(jì),聚合函數(shù)會(huì)根據(jù)返回值的類型用默認(rèn)值0或者NULL來(lái)代替聚合函數(shù)的返回值。
            2.3 GROUP BY [Expressions] WITH CUBE | ROLLUP:
            首先需要說(shuō)明的是Group By All 語(yǔ)句是不能和CUBE 和 ROLLUP 關(guān)鍵字一起使用的。
            首先先說(shuō)說(shuō)CUBE關(guān)鍵字,以下是SQL Server 2000聯(lián)機(jī)幫助中的說(shuō)明:
            指定在結(jié)果集內(nèi)不僅包含由 GROUP BY 提供的正常行,還包含匯總行。在結(jié)果集內(nèi)返回每個(gè)可能的組和子組組合的 GROUP BY 匯總行。GROUP BY 匯總行在結(jié)果中顯示為 NULL,但可用來(lái)表示所有值。使用 GROUPING 函數(shù)確定結(jié)果集內(nèi)的空值是否是 GROUP BY 匯總值。
            結(jié)果集內(nèi)的匯總行數(shù)取決于 GROUP BY 子句內(nèi)包含的列數(shù)。GROUP BY 子句中的每個(gè)操作數(shù)(列)綁定在分組 NULL 下,并且分組適用于所有其它操作數(shù)(列)。由于 CUBE 返回每個(gè)可能的組和子組組合,因此不論指定分組列時(shí)所使用的是什么順序,行數(shù)都相同。
            我們通常的Group By語(yǔ)句是按照其后所跟的所有字段進(jìn)行分組,而如果加入了CUBE關(guān)鍵字以后,那么系統(tǒng)將根據(jù)所有字段進(jìn)行分組的基礎(chǔ)上,還會(huì)通過(guò)對(duì)所有這些分組字段所有可能存在的組合形成的分組條件進(jìn)行分組計(jì)算。由于上面舉的例子過(guò)于簡(jiǎn)單,這里就再適合了,現(xiàn)在我們的數(shù)據(jù)集將換一個(gè)場(chǎng)景,一個(gè)表中包含人員的基本信息:?jiǎn)T工所在的部門編號(hào)(C_EMPLINFO_DEPTID)、員工性別(C_EMPLINFO_SEX)、員工姓名(C_EMPLINFO_NAME)等。那么我現(xiàn)在想知道每個(gè)部門各個(gè)性別的人數(shù),那么我們可以通過(guò)如下語(yǔ)句得到:
            SELECT C_EMPLINFO_DEPTID, C_EMPLINFO_SEX, COUNT(*) AS C_EMPLINFO_TOTALSTAFFNUM
            FROM T_PERSONNEL_EMPLINFO
            GROUP BY C_EMPLINFO_DEPTID, C_EMPLINFO_SEX
            但是如果我現(xiàn)在希望知道:
            1. 所有部門有多少人(這里相當(dāng)于就不進(jìn)行分組了,因?yàn)檫@里已經(jīng)對(duì)員工的部門和性別沒(méi)有做任何限制了,但是這的確也是一種分組條件的組合方式);
            2. 每種性別有多人(這里實(shí)際上是僅僅根據(jù)性別(C_EMPLINFO_SEX)進(jìn)行分組);
            3. 每個(gè)部門有多少人(這里僅僅是根據(jù)部門(C_EMPLINFO_DEPTID)進(jìn)行分組);那么我們就可以使用ROLLUP語(yǔ)句了。
            SELECT C_EMPLINFO_DEPTID, C_EMPLINFO_SEX, COUNT(*) AS C_EMPLINFO_TOTALSTAFFNUM
            FROM T_PERSONNEL_EMPLINFO
            GROUP BY C_EMPLINFO_DEPTID, C_EMPLINFO_SEX WITH CUBE
            那么這里你可以看到結(jié)果集中多出了很多行,而且結(jié)果集中的某一個(gè)字段或者多個(gè)字段、甚至全部的字段都為NULL,請(qǐng)仔細(xì)看一下你就會(huì)發(fā)現(xiàn)實(shí)際上這些記錄就是完成了上面我所列舉的所有統(tǒng)計(jì)數(shù)據(jù)的展現(xiàn)。使用過(guò)SQL Server 2005或者RDLC的朋友們一定對(duì)于矩陣的小計(jì)和分組功能有印象吧,是不是都可以通過(guò)這個(gè)得到答案。我想RDLC中對(duì)于分組和小計(jì)的計(jì)算就是通過(guò)Group By的CUBE和ROLLUP關(guān)鍵字來(lái)實(shí)現(xiàn)的。(個(gè)人意見,未證實(shí))
            CUBE關(guān)鍵字還有一個(gè)極為相似的兄弟ROLLUP, 同樣我們先從這英文入手,ROLL UP是“向上卷”的意思,如果說(shuō)CUBE的組合是絕對(duì)自由的,那么ROLLUP的組合就需要有點(diǎn)約束了。我們先來(lái)看看SQL Server 2000的聯(lián)機(jī)中對(duì)ROLLUP關(guān)鍵字的定義:
            指定在結(jié)果集內(nèi)不僅包含由 GROUP BY 提供的正常行,還包含匯總行。按層次結(jié)構(gòu)順序,從組內(nèi)的最低級(jí)別到級(jí)別匯總組。組的層次結(jié)構(gòu)取決于指定分組列時(shí)所使用的順序。更改分組列的順序會(huì)影響在結(jié)果集內(nèi)生成的行數(shù)。
            那么這個(gè)順序是什么呢?對(duì)了就是Group By 后面字段的順序,排在靠近Group By的分組字段的級(jí)別高,然后是依次遞減。如:Group By Column1, Column2, Column3。那么分組級(jí)別從高到低的順序是:Column1 > Column2 > Column3。還是看我們前面的例子,SQL語(yǔ)句中我們僅僅將CUBE關(guān)鍵字替換成ROLLUP關(guān)鍵字,如:
            SELECT C_EMPLINFO_DEPTID, C_EMPLINFO_SEX, COUNT(*) AS C_EMPLINFO_TOTALSTAFFNUM
            FROM T_PERSONNEL_EMPLINFO
            GROUP BY C_EMPLINFO_DEPTID, C_EMPLINFO_SEX WITH ROLLUP
            和CUBE相比,返回的數(shù)據(jù)行數(shù)減少了不少。:),仔細(xì)看一下,除了正常的Group By語(yǔ)句后,數(shù)據(jù)中還包含了:
            1. 部門員工數(shù);(向上卷了一次,這次先去掉了員工性別的分組限制)
            2. 所有部門員工數(shù);(向上又卷了依次,這次去掉了員工所在部門的分組限制)。
            在現(xiàn)實(shí)的應(yīng)用中,對(duì)于報(bào)表的一些統(tǒng)計(jì)功能是很有幫助的。
            這里還有一個(gè)問(wèn)題需要補(bǔ)充說(shuō)明一下,如果我們使用ROLLUP或者CUBE關(guān)鍵字,那么將產(chǎn)生一些小計(jì)的行,這些行中被剔除在分組因素之外的字段將會(huì)被設(shè)置為NULL,那么還存在一種情況,比如在作為分組依據(jù)的列表中存在可空的行,那么NULL也會(huì)被作為一個(gè)分組表示出來(lái),所以這里我們就不能僅僅通過(guò)NULL來(lái)判斷是不是小計(jì)記錄了。下面的例子展示了這里說(shuō)得到的情況。還是我們前面提到的水果例子,現(xiàn)在我們?cè)诿糠N商品后面增加一個(gè)“折扣列”(Discount),用于顯示對(duì)應(yīng)商品的折扣,這個(gè)數(shù)值是可空的,也就是可以通過(guò)NULL來(lái)表示沒(méi)有對(duì)應(yīng)的折扣信息。數(shù)據(jù)集如下所示:
            FruitNameProductPlacePriceDiscount
            AppleChina$1.10.8
            AppleJapan$2.10.9
            AppleUSA$2.51.0
            OrangeChina$0.8NULL
            BananaChina$3.1NULL
            PeachUSA$3.0NULL
            現(xiàn)在我們要統(tǒng)計(jì)“各種折扣對(duì)應(yīng)有多少種商品,并總計(jì)商品的總數(shù)。”,那么我們可以通過(guò)如下的SQL語(yǔ)句來(lái)完成:
            SELECT COUNT(*) AS ProductCount, Discount
            FROM T_TEST_FRUITINFO
            GROUP BY Discount WITH ROLLUP
            好了,運(yùn)行一下,你會(huì)發(fā)現(xiàn)數(shù)據(jù)都正常出來(lái)了,按照如上的數(shù)據(jù)集,結(jié)果如下所示:
            ProductCountDiscount
            3NULL
            10.8
            10.9
            11.0
            6NULL
            好了,各種折扣的商品數(shù)量都出來(lái)了,但是在顯示“沒(méi)有折扣商品”和“商品小計(jì)”的時(shí)候判斷上確存在問(wèn)題,因?yàn)榇嬖趦蓷lDiscount為Null的記錄。是哪一條呢?通過(guò)分析數(shù)據(jù)我們知道第一條數(shù)據(jù)(3, Null)應(yīng)該對(duì)應(yīng)沒(méi)有折扣商品的數(shù)量,而(6,Null)應(yīng)該對(duì)應(yīng)所有商品的數(shù)量。需要判斷這兩個(gè)具有不同意義的Null就需要引入一個(gè)聚合函數(shù)Grouping?,F(xiàn)在我們把語(yǔ)句修改一下,在返回值中使用Grouping函數(shù)增加一列返回值,SQL語(yǔ)句如下:
            SELECT COUNT(*) AS ProductCount, Discount, GROUPING(Discount) AS Expr1
            FROM T_TEST_FRUITINFO
            GROUP BY Discount WITH ROLLUP
            這個(gè)時(shí)候,我們?cè)倏纯催\(yùn)行的結(jié)果:
            ProductCountDiscountExpr1
            3NULL0
            10.80
            10.90
            11.00
            6NULL1
            對(duì)于根據(jù)指定字段Grouping中包含的字段進(jìn)行小計(jì)的記錄,這里會(huì)標(biāo)記為1,我們就可以通過(guò)這個(gè)標(biāo)記值將小計(jì)記錄從判斷那些由于ROLLUP或者CUBE關(guān)鍵字產(chǎn)生的行。Grouping(column_name)可以帶一個(gè)參數(shù),Grouping就會(huì)去判斷對(duì)應(yīng)的字段值的NULL是否是由ROLLUP或者CUBE產(chǎn)生的特殊NULL值,如果是那么就在由Grouping聚合函數(shù)產(chǎn)生的新列中將值設(shè)置為1。注意Grouping只會(huì)檢查Column_name對(duì)應(yīng)的NULL來(lái)決定是否將值設(shè)置為1,而不是完全由此列是否是由ROLLUP或者CUBE關(guān)鍵字自動(dòng)添加來(lái)決定的。
            2.3 Group By 和 Having, Where ,Order by語(yǔ)句的執(zhí)行順序:
            最后要說(shuō)明一下的Group By, Having, Where, Order by幾個(gè)語(yǔ)句的執(zhí)行順序。一個(gè)SQL語(yǔ)句往往會(huì)產(chǎn)生多個(gè)臨時(shí)視圖,那么這些關(guān)鍵字的執(zhí)行順序就非常重要了,因?yàn)槟惚仨毩私膺@個(gè)關(guān)鍵字是在對(duì)應(yīng)視圖形成前的字段進(jìn)行操作還是對(duì)形成的臨時(shí)視圖進(jìn)行操作,這個(gè)問(wèn)題在使用了別名的視圖尤其重要。以上列舉的關(guān)鍵字是按照如下順序進(jìn)行執(zhí)行的:Where, Group By, Having, Order by。首先where將最原始記錄中不滿足條件的記錄刪除(所以應(yīng)該在where語(yǔ)句中盡量的將不符合條件的記錄篩選掉,這樣可以減少分組的次數(shù)),然后通過(guò)Group By關(guān)鍵字后面指定的分組條件將篩選得到的視圖進(jìn)行分組,接著系統(tǒng)根據(jù)Having關(guān)鍵字后面指定的篩選條件,將分組視圖后不滿足條件的記錄篩選掉,然后按照Order By語(yǔ)句對(duì)視圖進(jìn)行排序,這樣最終的結(jié)果就產(chǎn)生了。在這四個(gè)關(guān)鍵字中,只有在Order By語(yǔ)句中才可以使用最終視圖的列名,如:
            SELECT FruitName, ProductPlace, Price, ID AS IDE, Discount
            FROM T_TEST_FRUITINFO
            WHERE (ProductPlace = N’china’)
            ORDER BY IDE
            這里只有在ORDER BY語(yǔ)句中才可以使用IDE,其他條件語(yǔ)句中如果需要引用列名則只能使用ID,而不能使用IDE。