Dict.CN 在線詞典, 英語學(xué)習(xí), 在線翻譯

          都市淘沙者

          荔枝FM Everyone can be host

          統(tǒng)計

          留言簿(23)

          積分與排名

          優(yōu)秀學(xué)習(xí)網(wǎng)站

          友情連接

          閱讀排行榜

          評論排行榜

          查詢之order by,group by和having的使用 (轉(zhuǎn))

          (1)order by

           ORDER BY子句的語法為:

          SELECT column1, SUM(column2) FROM "list-of-tables"

          ORDER BY "column-list" [ASC | DESC];

          [ ] = optional

          ORDER BY是一個可選的子句,它允許你根據(jù)指定要order by的列來以上升或者下降的順序來顯示查詢的結(jié)果。例如:

          ASC = Ascending Order – 這個是缺省的

          DESC = Descending Order

          下面舉個例子:

          SELECT employee_id, dept, name, age, salary

          FROM employee_info

          WHERE dept = 'Sales'

          ORDER BY salary;

          這條SQL語句將從employee_info表中列dept等于'Sales'選擇employee_id,、dept、 name、 age和 salary,并且根據(jù)他們的salary按升序的順序來列出檢索結(jié)果。

          如果你想對多列排序的話,那么在列與列之間要加上逗號,比如 :

          SELECT employee_id, dept, name, age, salary

          FROM employee_info

          WHERE dept = 'Sales'

          ORDER BY salary, age DESC;

          (2)group by

          一、首先講講GROUP BY 子句語法:

          SELECT column1, SUM(column2) FROM "list-of-tables"

          GROUP BY "column-list";

          這個GROUP BY子句將集中所有的行在一起,它包含了指定列的數(shù)據(jù)以及允許合計函數(shù)來計算一個或者多個列。當然最好解釋的方法是給出一個例子啦:

          假設(shè)我們將從employee表中搜索工資最高的列,可以使用以下的SQL語句:

          SELECT max(salary), dept

          FROM employee

          GROUP BY dept;

          這條語句將在每一個單獨的部門中選擇工資最高的工資。結(jié)果他們的salary和dept將被返回。

          二、group by 從英文里理解就是分組。必須有“聚合函數(shù)”來配合才能使用,使用時至少需要一個分組標志字段。
           
          什么是“聚合函數(shù)”?
            像sum()、count()、avg()等都是“聚合函數(shù)”
            使用group by 的目的就是要將數(shù)據(jù)分類匯總。

            一般如:
              select 單位名稱,count(職工id),sum(職工工資) form [某表]
              group by 單位名稱
              這樣的運行結(jié)果就是以“單位名稱”為分類標志統(tǒng)計各單位的職工人數(shù)和工資總額。

            在sql命令格式使用的先后順序上,group by 先于 order by。
           
            select 命令的標準格式如下:
           
             SELECT select_list
             [ INTO new_table ]
             FROM table_source
             [ WHERE search_condition ]
             [ GROUP BY group_by_expression ]
             [ HAVING search_condition ]
             [ ORDER BY order_expression [ ASC | DESC ] ]

          三、理解group by:

          表1:

           type

           udate

           mp3

           2006-3-2

           flash

           2006-1-2

           mp3

           2006-2-2

           
          在表1中,假設(shè)要取出最后更新的某一類型(type)產(chǎn)品的日期
          那么就要使用group by type的方式
          select type from 表1 group by type
          但這樣就無法讀到udate
           
          再來
          select type,udate from 表1 group by type
          這種寫法是錯誤的。
          原因是type和udate 不是一對一的關(guān)系。就是說一種type有幾個udate
          所以
          selct ** group by ** 之后沒辦法組織形成新的表,不知道要取哪個udate
           
          再來
          select type,max(udate) from 表1 group by type
          這樣就正確了。
          取的是最大的udate ,一對一成立。

          四、GROUP BY... 被附加于SQL 是因為聚會函數(shù) (如 SUM) 每次都返回所有列值的合計,沒有GROUP BY函數(shù)是不可能找到列值的單個分組的合計數(shù)。

          語法

          SELECT column,SUM(column) FROM table GROUP BY column

          -----------------------------------------------

          GROUP BY 示例

          這個 "Sales" 表:

          Company Amount
          W3Schools 5500
          IBM 4500
          W3Schools 7100

          和這個SQL語句:

          SELECT Company, SUM(Amount) FROM Sales

          返回這個結(jié)果:

          Company SUM(Amount)
          W3Schools 17100
          IBM 17100
          W3Schools 17100

          上面的代碼是不正確的,因為被返回的列不是部分合計。GROUP BY 子句將解決這個問題。

          SELECT Company,SUM(Amount) FROM Sales            GROUP BY Company

          返回結(jié)果:

          Company SUM(Amount)
          W3Schools 12600
          IBM 4500

          五、
          SQL Group by 學(xué)習(xí) 及相關(guān)應(yīng)注意的地方
           
              在select 語句中可以使用group by 子句將行劃分成較小的組,然后,使用聚組函數(shù)返回每一個組的匯總信息,另外,可以使用having子句限制返回的結(jié)果集。group by 子句可以將查詢結(jié)果分組,并返回行的匯總信息Oracle 按照group by 子句中指定的表達式的值分組查詢結(jié)果。

             在帶有g(shù)roup by 子句的查詢語句中,在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚組函數(shù)

             select max(sal),job emp group by job;
             (注意max(sal),job的job并非一定要出現(xiàn),但有意義)

             查詢語句的select 和group by ,having 子句是聚組函數(shù)唯一出現(xiàn)的地方,在where 子句中不能使用聚組函數(shù)。

            select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno;

            當在gropu by 子句中使用having 子句時,查詢結(jié)果中只返回滿足having條件的組。在一個sql語句中可以有where子句和having子句。having 與where 子句類似,均用于設(shè)置限定條件
           
            where 子句的作用是在對查詢結(jié)果進行分組前,將不符合where條件的行去掉,即在分組之前過濾數(shù)據(jù),條件中不能包含聚組函數(shù),使用where條件顯示特定的行。
            having 子句的作用是篩選滿足條件的組,即在分組之后過濾數(shù)據(jù),條件中經(jīng)常包含聚組函數(shù),使用having 條件顯示特定的組,也可以使用多個分組標準進行分組。

            查詢每個部門的每種職位的雇員數(shù)
            select deptno,job,count(*) from emp group by deptno,job;

          注意:

                  group by 不能對別名進行分組排序.舉例如下:

          錯誤SQL:

          SELECT to_char(BASICROLL.ROLLDATE,'yyyy-mm') AS YEARDATE,

             DEPTDICT.CNNAME DEPTNAME,
              COUNT(BASICROLL.ID) AS PROJCOUNT

          FROM BASICROLL LEFT JOIN DEPTDICT ON BASICROLL.ARRDEPTDICTID=DEPTDICT.ID

          WHERE DEPTDICT.CNNAME <> '無'

          GROUP BY YEARDATE, DEPTDICT.CNNAME                      1
          ORDER BY YEARDATE DESC                                                  2

           作者原意是將記錄按年月,部門進行分組.并倒序排序.但上面的GROUP BY因為用了別名,所以會提示SQL語法錯誤.如果將上面1,2二句改成:
             

          GROUP BY BASICROLL.ROLLDATE, DEPTDICT.CNNAME                      3

          ORDER BY BASICROLL.ROLLDATE  DESC                                                4

          如上3,4二句,又會不合原意,因為BASICROLL.ROLLDATE  包括了年月日.這樣分組得出的是按年月日來分組,而不是單純的年月了.所以正確的SQL應(yīng)該是這樣的.

          正確的SQL

          SELECT to_char(BASICROLL.ROLLDATE,'yyyy-mm') AS YEARDATE,

             DEPTDICT.CNNAME DEPTNAME,
              COUNT(BASICROLL.ID) AS PROJCOUNT

          FROM BASICROLL LEFT JOIN DEPTDICT ON BASICROLL.ARRDEPTDICTID=DEPTDICT.ID

          WHERE DEPTDICT.CNNAME <> '無'

          GROUP BY to_char(BASICROLL.ROLLDATE,'yyyy-mm'), DEPTDICT.CNNAME                     

          ORDER BY to_char(BASICROLL.ROLLDATE,'yyyy-mm') DESC                                                 
          以上的注意部分為本人在項目開發(fā)過程中經(jīng)驗所得.

          來自:http://gyapollo.yculblog.com/post.1116750.html

          六、例子

          1> select * from bank_info
          2> go
           bankno acctround
           ------ ---------
           123456 1        
           123456 2        


           

          (2 rows affected)
          1> select * from bank_info where acctround='1' group by bankno order by bankno
          2> go
           bankno acctround
           ------ ---------
           123456 1        
           123456 2        


           

          (2 rows affected)
          1> select * from bank_info where acctround='1' order by bankno
          2> go
           bankno acctround
           ------ ---------
           123456 1        


           

          (1 row affected)
          1> select * from bank_info
          2> go
           bankno acctround
           ------ ---------
           123456 1        
           123456 2        


           

          (2 rows affected)
          1> select * from bank_info where acctround='1' group by bankno,acctround order by bankno
          2> go
           bankno acctround
           ------ ---------
           123456 1        


           

          (1 row affected)


          group by bankno,acctround的意思是找出bankno,acctround兩列完全相同的不同行作為一組.那上面的數(shù)據(jù)就分成兩組了,因為acctround不同,而結(jié)果需要acctround='1'的組.所以只有一行結(jié)果.如果是group by bankno,那么兩行會合成一行.它并沒有先通過where分析出只有一行符合結(jié)果集,再group就只有一行結(jié)果了.這里的問題是where和group誰先誰后分析的問題?在這個問題的上下文中,本來的group by bankno就沒有任何意義.其實是這樣的: 

          或者是: 

          select bankno,sum(money) from bankdiff group by bankno; 

          又或者是: 

          select bankno,acctround,sum(money) from bankdiff where acctround='1' group by bankno,acctround;
           

          不可能指定acctround又不把它放在groub by中的.

           

          1> select * from bank_info group by bankno
          2> go
           bankno acctround
           ------ ---------
           123456 1        
           123456 2 


           

          可見這個group by沒有意義.因為它有select *,而acctround不一樣,就不能只顯示一行出來.把select * 改成 select bankno就只有一行結(jié)果了.


           

          總結(jié):使用group by必需明確你分組的意義,是否有必要這一個列或幾個列來確定一個有意義的組,而需要顯示的結(jié)果行的列是否和group by子句中的列名相沖突.一般不在group by子句中的列名都不會直接在select中顯示出來.因為它們要分成一組來或者做些運算再顯示.如sum(money)等.

          (3)having

          一、下面先給出HAVING子句的語法:

          SELECT column1, SUM(column2) FROM "list-of-tables"

          GROUP BY "column-list"

          HAVING "condition";

          這個HAVING子句允許你為每一個組指定條件,換句話說,可以根據(jù)你指定的條件來選擇行。如果你想使用HAVING子句的話,它應(yīng)該處再GROUP BY子句之后。

          下面將以一個例子來解釋HAVING子句。假設(shè)我們的employee表中包含雇員的name、departmen、salary和age。如果你想為每個部門中每個雇員選擇平均工資的話,你可以使用下面的SQL語句:

          SELECT dept, avg(salary)

          FROM employee

          GROUP BY dept;

          當然,如果你還想只計算和顯示salary大于20000的平均工資的話,你還可以加上HAVING子句:

          SELECT dept, avg(salary)

          FROM employee

          GROUP BY dept

          HAVING avg(salary) > 20000;

          二、HAVING... 被附加到SQL語句是因為WHER關(guān)鍵字不能被用于聚會函數(shù) (如 SUM),并且沒有HAVING...它將不可能測試結(jié)果條件。

          語法:

          SELECT column,SUM(column) FROM table            GROUP BY column            HAVING SUM(column) condition value

          這個 "Sales" 表:

          Company Amount
          W3Schools 5500
          IBM 4500
          W3Schools 7100

          和這個SQL語句:

          SELECT Company,SUM(Amount) FROM Sales            GROUP BY Company            HAVING SUM(Amount)>10000

          返回這個結(jié)果

          Company SUM(Amount)
          W3Schools 12600

           

          posted on 2007-09-10 09:42 都市淘沙者 閱讀(859) 評論(0)  編輯  收藏 所屬分類: Oracle/Mysql/Postgres/

          主站蜘蛛池模板: 临海市| 嘉义市| 阿巴嘎旗| 兴海县| 洱源县| 措勤县| 祁门县| 犍为县| 科技| 昭觉县| 柏乡县| 凤城市| 兖州市| 通山县| 仁寿县| 施甸县| 重庆市| 清远市| 华宁县| 三门峡市| 乐陵市| 黑山县| 吉隆县| 那坡县| 孙吴县| 九龙城区| 丰顺县| 四子王旗| 濮阳县| 葵青区| 常德市| 达日县| 根河市| 开阳县| 高雄市| 平遥县| 乌拉特中旗| 康保县| 新民市| 宁安市| 九江市|