1. 程式人生 > >SQL group by分組查詢

SQL group by分組查詢

create server insert 一定的 ID all 註意 至少 滿足

本文導讀:在實際SQL應用中,經常需要進行分組聚合,即將查詢對象按一定條件分組,然後對每一個組進行聚合分析。創建分組是通過GROUP BY子句實現的。與WHERE子句不同,GROUP BY子句用於歸納信息類型,以匯總相關數據。GROUP BY的作用是通過一定的規則將一個數據集劃分成若幹個小的區域,然後針對若幹個小區域進行數據處理。

在SQL Server中使用的分組查詢是ORDER BY子句,使用ORDER BY子句要同聚合函數配合使用才能完成分組查詢,在SELECT查詢的字段中如果字段沒有使用聚合函數就必須出現在ORDER BY子句中(即SELECT後邊的字段名要麽出現在聚合函數中,要麽在ORDER BY子句中使用)

在分組查詢中還可以配合使用HAVING子句,定義查詢條件。

使用group by進行分組查詢

在使用group by關鍵字時,在select列表中可以指定的項目是有限制的,select語句中僅許以下幾項:

〉被分組的列

〉為每個分組返回一個值得表達式,例如用一個列名作為參數的聚合函數

group by 有一個原則,就是 select 後面的所有列中,沒有使用聚合函數的列,必須出現在 group by 後面(重要)

group by實例

實例一

數據表:

姓名 科目 分數

張三 語文 80

張三 數學 98

張三 英語 65

李四 語文 70

李四 數學 80

李四 英語 90

期望查詢結果:

姓名 語文 數學 英語

張三 80 98 65

李四 70 80 90

代碼

SQL 代碼 復制

create table testScore

(

tid int primary key identity(1,1),

tname varchar(30) null,

ttype varchar(10) null,

tscor int null

)

go

---插入數據

insert into testScore values (‘張三‘,‘語文‘,80)

insert into testScore values (‘張三‘,‘數學‘,98)

insert into testScore values (‘張三‘,‘英語‘,65)

insert into testScore values (‘李四‘,‘語文‘,70)

insert into testScore values (‘李四‘,‘數學‘,80)

insert into testScore values (‘李四‘,‘英語‘,90)

select tname as ‘姓名‘ ,

max(case ttype when ‘語文‘ then tscor else 0 end) ‘語文‘,

max(case ttype when ‘數學‘ then tscor else 0 end) ‘數學‘,

max(case ttype when ‘英語‘ then tscor else 0 end) ‘英語‘

from testScore

group by tname

實例二

有如下數據:(為了看得更清楚,我並沒有使用國家代碼,而是直接用國家名作為Primary Key)

國家(country)

人口(population)

中國

600

美國

100

加拿大

100

英國

200

法國

300

日本

250

德國

200

墨西哥

50

印度

250

根據這個國家人口數據,統計亞洲和北美洲的人口數量。應該得到下面這個結果。

人口

亞洲

1100

北美洲

250

其他

700

代碼

SQL 代碼 復制

SELECT SUM(population),

CASE country

WHEN ‘中國‘ THEN ‘亞洲‘

WHEN ‘印度‘ THEN ‘亞洲‘

WHEN ‘日本‘ THEN ‘亞洲‘

WHEN ‘美國‘ THEN ‘北美洲‘

WHEN ‘加拿大‘ THEN ‘北美洲‘

WHEN ‘墨西哥‘ THEN ‘北美洲‘

ELSE ‘其他‘ END

FROM Table_A

GROUP BY CASE country

WHEN ‘中國‘ THEN ‘亞洲‘

WHEN ‘印度‘ THEN ‘亞洲‘

WHEN ‘日本‘ THEN ‘亞洲‘

WHEN ‘美國‘ THEN ‘北美洲‘

WHEN ‘加拿大‘ THEN ‘北美洲‘

WHEN ‘墨西哥‘ THEN ‘北美洲‘

ELSE ‘其他‘ END;

同樣的,我們也可以用這個方法來判斷工資的等級,並統計每一等級的人數。SQL代碼如下;

SQL 代碼 復制

SELECT

CASE WHEN salary <= 500 THEN ‘1‘

WHEN salary > 500 AND salary <= 600 THEN ‘2‘

WHEN salary > 600 AND salary <= 800 THEN ‘3‘

WHEN salary > 800 AND salary <= 1000 THEN ‘4‘

ELSE NULL END salary_class,

COUNT(*)

FROM Table_A

GROUP BY

CASE WHEN salary <= 500 THEN ‘1‘

WHEN salary > 500 AND salary <= 600 THEN ‘2‘

WHEN salary > 600 AND salary <= 800 THEN ‘3‘

WHEN salary > 800 AND salary <= 1000 THEN ‘4‘

ELSE NULL END;

對於groupby後面一般都是跟一個列名,但在該例子中通過case語句使分組變得跟強大了。

實例三

有如下數據

國家(country)

性別(sex)

人口(population)

中國

1

340

中國

2

260

美國

1

45

美國

2

55

加拿大

1

51

加拿大

2

49

英國

1

40

英國

2

60

按照國家和性別進行分組,得出結果如下

國家

中國

340

260

美國

45

55

加拿大

51

49

英國

40

60

代碼

SQL 代碼 復制

SELECT country,

SUM( CASE WHEN sex = ‘1‘ THEN

population ELSE 0 END), --男性人口

SUM( CASE WHEN sex = ‘2‘ THEN

population ELSE 0 END) --女性人口

FROM Table_A

GROUP BY country;

GROUP BY子句中的NULL值處理

當GROUP BY子句中用於分組的列中出現NULL值時,將如何分組呢?SQL中,NULL不等於NULL(在WHERE子句中有過介紹)。然而,在GROUP BY子句中,卻將所有的NULL值分在同一組,即認為它們是“相等”的。

HAVING子句

GROUP BY子句分組,只是簡單地依據所選列的數據進行分組,將該列具有相同值的行劃為一組。而實際應用中,往往還需要刪除那些不能滿足條件的行組,為了實現這個功能,SQL提供了HAVING子句。語法如下。

SELECT column, SUM(column)

FROM table

GROUP BY column

HAVING SUM(column) condition value

說明:HAVING通常與GROUP BY子句同時使用。當然,語法中的SUM()函數也可以是其他任何聚合函數。DBMS將HAVING子句中的搜索條件應用於GROUP BY子句產生的行組,如果行組不滿足搜索條件,就將其從結果表中刪除。

HAVING子句的應用

從TEACHER表中查詢至少有兩位教師的系及教師人數。

實現代碼:

SQL 代碼 復制

SELECT DNAME, COUNT(*) AS num_teacher

FROM TEACHER

GROUP BY DNAME

HAVING COUNT(*)>=2

HAVING子句與WHERE子句的區別

HAVING子句和WHERE子句的相似之處在於,它也定義搜索條件。但與WHERE子句不同,HAVING子句與組有關,而不是與單個的行有關。

1、如果指定了GROUP BY子句,那麽HAVING子句定義的搜索條件將作用於這個GROUP BY子句創建的那些組。

2、如果指定WHERE子句,而沒有指定GROUP BY子句,那麽HAVING子句定義的搜索條件將作用於WHERE子句的輸出,並把這個輸出看作是一個組。

3、如果既沒有指定GROUP BY子句也沒有指定WHERE子句,那麽HAVING子句定義的搜索條件將作用於FROM子句的輸出,並把這個輸出看作是一個組。

4、在SELECT語句中,WHERE和HAVING子句的執行順序不同。在本書的.1.2節介紹的SELECT語句的執行步驟可知,WHERE子句只能接收來自FROM子句的輸入,而HAVING子句則可以接收來自GROUP BY子句、WHERE子句和FROM子句的輸入。

5)

-- group by .... with rollup 的使用

CREATE TABLE #test (

Name varchar(10)

, [procedure] CHAR(1)

, model varchar(5)

, quantity int);

INSERT intO #testSELECT ‘A‘, ‘1‘, ‘φ‘, 500

union ALLSELECT ‘A‘, ‘1‘, ‘φ‘, 600

union ALLSELECT ‘A‘, ‘1‘, ‘φ‘, 500

union ALLSELECT ‘A‘, ‘2‘, ‘φ‘, 700

union ALLSELECT ‘A‘, ‘2‘, ‘φ‘, 200

union ALLSELECT ‘B‘, ‘1‘, ‘φ‘, 1000;

SELECT

case WHEN GROUPING(Name) = 1 THEN ‘總計‘

WHEN GROUPING(Name) = 0 AND GROUPING([procedure]) = 1 THEN Name + ‘合計‘

WHEN GROUPING(Name) = 0 AND GROUPING([procedure]) = 0 AND GROUPING([model]) = 1 THEN Name + ‘的‘ + [procedure] + ‘小計‘

else Name end AS Name

, case WHEN GROUPING([model]) = 1 THEN ‘‘ else [procedure] end AS [procedure]

, isnull(model, ‘‘) AS model

, sum(quantity) AS quantity

FROM #test

group by Name, [procedure], model with rollup

procedure model quantity----------------- --------- ----- ----------

-A 1 φ 500

A 1 φ 1100

A的小計 1600

A 2 φ 200

A 2 φ 700

A的小計 900

A合計 2500

B 1 φ 1000

B的小計 1000

B合計 1000

總計 3500

CUBE運算符生成的結果集是多維數據集,多維數據集是事實數據的擴展,事實數據即記錄個別時間的數據,擴展建立在用戶準備分析的列上,這些列被稱為維,多維數據集是一個結果集,其中包含各緯度所有可能的交叉表格.

CUBE運算符是在Select語句的group by子句中指定的,group by應指定維度列和關鍵字with cube,結果集將包括維度列中各值的所有可能組合.

示例1.

Sql語句如下:

select * from student

select sex,sclass,sum(score) as 合計

from student

group by sex,sclass with cube

select sex,sclass,sum(score) as 合計

from student

group by sclass,sex with cube

Sql查詢時這樣運行:

1. 查詢到性別的第一個性別為男,則先查詢男生,然後分班級

2. 查詢完成之後,對性別為Sex為男的數據進行合計

3. 查詢性別為女的數據,查詢完成之後同樣也進行合計

4. 不分性別、班級進行合計匯總

5. 以上均是以性別為組來分類,因為至此時關於性別的所有匯總都已經完成

6. 按照sclass進行分組匯總.

註意:

1. 分類依據並不是根據select 中的順序,而是根據group by中的順序.

2. 盡量按照使select和group by中的字段順序一致,這樣在顯示起來看著更舒服,具體情況具體分析.

對於上述查詢的結果,我們可以看出,數據中存在空置問題,綁定到GridView後顯示如下:

此中效果並沒有達到能夠滿足實際項目中的需要,所以,我們對Sql語句應進行改進.

使用Grouping區分空值.

如何區分使用CUBE之後產生的空值和實際查詢中得到的空值.這個問題可以用grouping函數來解決.如果列中的值來來自查詢數據,則grouping返回0,如果列中的值是cube產生的空值,則返回1

示例2.

Sql如下:

select case when(grouping(sex)=1) then ‘小記‘ else sex

end as 性別,

case when(grouping(sclass)=1) then ‘小記‘ else sclass

end as 班級,

sum(score)

from student

group by sex,sclass with cube

在頁面上顯示時如下:

CUBE可以生成n維的多維數據集,即具有任意維目的多維數據集,只有一個維度的多維數據集可用於生成合計.

示例3:

SQL:

select case when(grouping(sex)=1) then ‘合計‘ else sex end as 性別,

sum(score) as 合計

from student

group by sex with cube

生成許多維度的數據集合結果可能很大,辦法就是生成一個大的視圖,選擇顯示即可.

文章出處:http://www.studyofnet.com/news/247.html

SQL group by分組查詢