赛迪网 > IT技术 编程语言 > 文章
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

SQL查询语言基本教程(2)

发布时间:2006.08.16 02:59     来源:plwww    作者:

SQL查询语言基本教程(2)

三、GROUP BY...语句
    GROUP BY... 语句实现纪录分组功能,它通常需要和上面我们提到过的统计函数 SUM、COUNT 等联合使用,它的语法为:

 SELECT column1[, column2]
 FROM table1[,table2]
 WHERE conditions
 GROUP BY column1[, column2]
 ORDER BY column1[, column2]

范例四:计算学生成绩及总成绩
    我们依然使用上一章使用的数据库 c:\db4.mdb,在其中加入一个名字为 db2 的表,表的结构以及数据如下:
 
字段名 学生 科目 成绩
 张严 语文 86.5
 李永 语文 93
 王为 语文 91
 张严 数学 96.5
 李永 数学 90
 王为 数学 87
 张严 英语 80.5
 李永 英语 94
 王为 英语 98

    建立新工程,加入DAO定义库。在Form1中加入一个ListBox控件,然后在Form_load中加入以下代码:

Private Sub Form_Load()
    Dim rsTemp As Recordset
    Dim dbTemp As Database
    Dim astr As String
   
    Set dbTemp = DBEngine(0).OpenDatabase("c:\db4.mdb", dbOpenSnapshot)
    astr = "SELECT SUM(db2.成绩)AS rTotal, FORMAT((AVG(db2.成绩)),'###.#') AS rAVG, " & _
            " (db2.学生) AS Student FROM db2 GROUP BY db2.学生"

    Set rsTemp = dbTemp.OpenRecordset(astr)
    If rsTemp.RecordCount > 0 Then
        rsTemp.MoveFirst
        Do Until rsTemp.EOF
            List1.AddItem rsTemp![Student] & Chr(5) & rsTemp![rTotal] & _
                "       " & rsTemp![rAVG]
            rsTemp.MoveNext
        Loop
    End If
End Sub
    在上面的代码中,我们利用GROUP BY将纪录根据学生姓名分组,再建立了两个统计字段rTotal和rAvg并分别利用
统计函数SUM和AVG分别统计各个分组的总成绩以及平均成绩。要注意的是,在SELECT语句中出现的字段,如果没有包含
在统计函数内的话,都要包含在GROUP BY子句中。
    另外在上面的SQL查询中我们还使用了FORMAT子句,这是SQL中的转换和格式化语句中的一个,该语句的语法同VB中
的Format语句是一样的,相似的语句还有FIX语句。需要注意的一点是,虽然在Microsoft JET Engine 中的SQL语法和
ANSI决大部分是一样的,但是有一些还是保留了“微软特色”,特别是象这一类的转换和格式化语句,例如FORMAT就是
ANSI中没有的。而象其它数据库,诸如oracle也有各自的SQL语法扩展。在使用不同数据库进行SQL查询时要注意这一点。
    在GROUP BY 语句中还可以连接使用HAVING子句。该语句同GROUP BY的关系就如同WHERE子句同SELECT的关系类似,
WHERE子语句为SELECT所选择的列设置条件,而HAVING子语句是给由GROUP BY创建的组设置条件。例如如果将上面的范例
中的astr改变为如下的字符串:

astr = "SELECT SUM(db2.成绩)AS rTotal, FORMAT((AVG(db2.成绩)),'###.#') " & _
            "AS rAVG, (db2.学生) AS Student FROM db2 GROUP BY db2.学生" & _
            " HAVING (AVG(db2.成绩))>=90"

则在List中就将只会列出平均成绩大于90分的学生的成绩和名字。

范例五:获得分数高于总平均分数的学生及科目
    我们仍然使用上面建立的db2表。建立新工程,加入DAO定义库。在Form1中加入一个ListBox控件和一个Label控件
然后在Form_load中加入以下代码:

Private Sub Form_Load()
    Dim rsTemp As Recordset
    Dim dbTemp As Database
    Dim astr As String
   
    Set dbTemp = DBEngine(0).OpenDatabase("c:\db4.mdb", dbOpenSnapshot)
   
    astr = "SELECT FORMAT(AVG(db2.成绩),'###.#') AS tAVG FROM db2"
    Set rsTemp = dbTemp.OpenRecordset(astr)
    Label1.Caption = "总平均成绩:" & rsTemp![tAVG]
    rsTemp.Close
    Set rsTemp = Nothing
   
    astr = "SELECT db2.成绩, db2.学生,db2.科目 FROM db2 WHERE db2.成绩 > " & _
            "(SELECT AVG(db2.成绩) FROM db2) GROUP BY db2.学生,db2.成绩,db2.科目 " & _
            "ORDER BY db2.学生"
    Set rsTemp = dbTemp.OpenRecordset(astr)
    If rsTemp.RecordCount > 0 Then
        rsTemp.MoveFirst
        Do Until rsTemp.EOF
            List1.AddItem rsTemp![学生] & "    " & rsTemp![科目] & "    " & rsTemp![成绩]
            rsTemp.MoveNext
        Loop
    End If
End Sub
    运行程序,在Lable1中列出总平均分数。在List1中列出了学生姓名、获得高于平均分数的科目以及科目成绩。
在上面的查询中,我们使用了一个嵌套查询,首先在子查询中获得所有科目总的平均分数,然后在查询中查询成绩字段
值大于平均分数的纪录。

四、TRANSFORM...PIVOT... 语句
    这是Microsoft JET Engine 3.5以上版本所特有的SQL查询语句,该语句的特点是可以建立一个交叉表格式的查询,
一个交叉表同电子表相类似。该语句可以将表中的某些数据作为行,某些数据作为列建立交叉表。该语句的语法如下:

 TRANSFORM condition [select opreation] PIVOT column

    其中condition是在交叉表中要显示的数据,select opreation 是一个SELECT...FROM... 查询,该查询形成交叉表的
航信息,PIVOT recordset中column为表中的一个字段,PIVOT子句使用该字段形成交叉表的列。

范例六:建立学生成绩表
    我们还是使用上面已经建立的db4.mdb中的db2表。首先建立一个新的工程,然后在Form1中加入一个DataGrid控件,然后
向工程中加入一个DataEnvironment,在Connection1上点击鼠标右键,在菜单中选择 properties... ,在属性窗口的 提供者
页面中选择 Microsoft JET 4.0 OLE DB Provider ,在 连接 页面的数据库名称输入框中输入 c:\db4.mdb ,然后点击 测试
连接 按钮,如果正常,点击确定退出。再在Connection1上点击鼠标右键,在菜单中选择 Add command 建立一个名为Command1
的命令,点击Command1右键菜单,选择 Properties... 项,然后在Command1属性窗口的General页面中选择 SQL Statement,
在SQL查询语句输入框中输入下面的查询:

 Transform SUM(db2.成绩)AS iRes SELECT db2.学生 FROM db2 GROUP BY db2.学生 Pivot db2.科目

    注意文本框回自动换行,不要输入回车。然后点击确定按钮。
    回到Form1,将DataGrid1的DataSource设置为DataEnvironment1,将DataMember设置为Command1,然后运行程序,可以看
到在DataGrid1中以表的形式列出了学生成绩,以学生为行,以成绩为列。运行后得到的表格效果如下:

 学生 数学 英语 语文
 李永 90 94 93
 王为 87 98 91
 张严 96.5 80.5 86.5

    再回到DataEnvironment界面,双击Command1就可以看到查询建立的数据列,在上面的查询共建立了4个数据列,其中三个
分别是科目分类,列中的数据为科目成绩,第一列为学生的名字,列中的数据为学生的名字。
    上面的查询中还使用了SUM子语句,这时因为对于GROUP BY来说,没有包含在统计函数内的列都要包含在GROUP BY中,如果
将字段db2.成绩包含在 GROUP BY 子语句中,就会使最终结果出现9行而不是3行。由于每个学生的每科成绩只有一个,所以可以
使用SUM函数将字段db2.成绩排除在GROUP BY外面。
    在下一章内,将向大家介绍SQL语言中的数据库结构定义部分以及数据操纵部分。

www.applevb.com


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· 如何建立控制台窗口以及同窗口交互 (12-03) · SQL查询语言基本教程(3) (04-06)
· 贪食蛇 (11-20) · 贪食蛇 (11-07)
· 让VB应用程序支持鼠标滚轮 (09-20) · 让VB应用程序支持鼠标滚轮 (11-14)
· Matthew Curland的VB函数指针调用 (08-26) · Matthew Curland的VB函数指针调用 (08-23)
· VB之道! (02-06) · VB之道! (04-14)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
[政务][电信][金融][农业][制造业][中小企业]
[CIO][ERP][协同][IT管理][中间件][电子商务]
[政策][地方][专家][评估][辞典][博客][社区]
· 专题:一路畅通构想曲——让出行不再遭遇堵车
· CIO工作亲历:企业ERP选型不能忽视"选人关"
· 综述:信息化建设给中国监狱带来的各种变化
· 金融业风险管理和法规遵从有五点需考虑的因素
· 保险业CIO关注:该如何建立统一高效的CRM体系
· 调查显示:多数CIO对IT规划仍存在困惑和误解
  博客·论坛 ·曾剑秋·项立刚·Java学习·网管