楼主: courset

[精华] 请高手指教一个SQL语句

[复制链接]
论坛徽章:
0
11#
 楼主| 发表于 2004-1-28 15:28 | 只看该作者
一般可以认为时间总是不相等,如果时间可能相等,那么guanglin4的SQL中< 改为 <= 是不是就可以了呢

使用道具 举报

回复
论坛徽章:
0
12#
发表于 2004-1-28 15:29 | 只看该作者
最初由 lodge 发布
[B]

呵呵, 问题就出在这里了, 例子里面不是这样的, 另外, 如果一个学生不是同一天同一门课只考试一次的话, 如何判断最近一次考试就成问题了. [/B]


例子里,每一学生每门考试的日期是好像是不同的。
1,1,70, 1/1/2004
1,1,71, 4/1/2004  《-- 最近一次

如果一个学生不是同一天同一门课只考试一次的话,只需要纪录考试的日期和时间。除非纪录有误,一个学生同一日期和时间同一门课考不只一次是不可能的。此类错误,可以通过unique index 类防止。

使用道具 举报

回复
论坛徽章:
0
13#
发表于 2004-1-28 15:40 | 只看该作者
最初由 courset 发布
[B]一般可以认为时间总是不相等,如果时间可能相等,那么guanglin4的SQL中< 改为 <= 是不是就可以了呢 [/B]


不能改为 <= 。如改为 <= ,一条记录都不会返回。因为自己的日期和时间相同。

使用道具 举报

回复
论坛徽章:
22
授权会员
日期:2005-10-30 17:05:332012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:36马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:36
14#
发表于 2004-1-28 15:47 | 只看该作者
在他的基础上加
insert into exam_score
select
1,1,71,'4/1/2004'
你看看

你说的对,我考虑不周全 ,我改了一下
select distinct * from exam_score a where exists (select *
from exam_score
where a.id=id and a.class=class having max(exam_date)=a.exam_date)

使用道具 举报

回复
论坛徽章:
59
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41灰彻蛋
日期:2011-10-28 14:15:35管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-02-18 11:43:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
15#
发表于 2004-1-28 17:27 | 只看该作者
最初由 guanglin4 发布
[B]

例子里,每一学生每门考试的日期是好像是不同的。
1,1,70, 1/1/2004
1,1,71, 4/1/2004  《-- 最近一次

如果一个学生不是同一天同一门课只考试一次的话,只需要纪录考试的日期和时间。除非纪录有误,一个学生同一日期和时间同一门课考不只一次是不可能的。此类错误,可以通过unique index 类防止。 [/B]


不好意思, 看走眼勒

使用道具 举报

回复
论坛徽章:
59
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41灰彻蛋
日期:2011-10-28 14:15:35管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-02-18 11:43:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
16#
发表于 2004-1-28 17:41 | 只看该作者
这样写也行
select distinct * from exam_score a
where exam_date=(select max(exam_date) from exam_score
where a.id=id and a.class=class)

这个写法虽然概念较为清楚, 但不利优化分析
实际上它是一种用结合作为检索条件的做法

它和下面这个句子几乎是等价的
select distinct a.* from exam_score a,  (select max(exam_date) from exam_score group by id, class) b
where a.id=b.id and a.class=b.class

使用道具 举报

回复
论坛徽章:
22
授权会员
日期:2005-10-30 17:05:332012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:36马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:36
17#
发表于 2004-1-28 21:41 | 只看该作者
最初由 lodge 发布
[B]这样写也行
select distinct * from exam_score a
where exam_date=(select max(exam_date) from exam_score
where a.id=id and a.class=class)

这个写法虽然概念较为清楚, 但不利优化分析
实际上它是一种用结合作为检索条件的做法

它和下面这个句子几乎是等价的
select distinct a.* from exam_score a,  (select max(exam_date) from exam_score group by id, class) b
where a.id=b.id and a.class=b.class [/B]


第一种写法跟我给出的exists的写法意思是一样的,都是求同,guanglin4用的排除。

至于等价方法,从语法到结果都是有问题的。

语法:
select distinct a.* from exam_score a,  (select id,class,max(exam_date) date from exam_score group by id, class) b
where a.id=b.id and a.class=b.class
b里的select应该加上id,class因为后面的where用上了b.id ,b.class ,还有对于b聚合函数产生的列应该确定别名。

结果:
join后的结果会跟select * from exam_score效果一样。因为两个表是并行扫描的,相当于一个自然连接,所以满足a.id=b.id and a.class=b.class 产生的笛卡儿积会和select * from exam_score一样。

而上面的
select distinct * from exam_score a
where exam_date=(select max(exam_date) from exam_score
where a.id=id and a.class=class)
是先扫描a然后将a的结果和b按a.id=id and a.class=class条件连接,满足exam_date=max(exam_date)的话就给出a的集合,相当于一个相关查询(存在测试)。

,意思没办法完全表达出来。

使用道具 举报

回复
论坛徽章:
59
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41灰彻蛋
日期:2011-10-28 14:15:35管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-02-18 11:43:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
18#
发表于 2004-1-28 21:49 | 只看该作者
恩, 有些笔误, 应该是这样
select distinct a.* from exam_score a, (select id, class, max(exam_date) exam_date from exam_score group by id, class) b
where a.id=b.id and a.class=b.class and a.exam_date=b.exam_date

如果你研究一下执行计划, 就会发现, 二者的执行计划几乎一样

偶第一次见到第一种写法的时候, 完全不能理解它的意思, 它的语法已经超出了SQL92的范围, 很难解释, 因为一个变量无论如何是不能等于一个集合的. 不过约定成俗, 很多数据库都支持这种写法, 当然, 这只是结合语句的另一种形式而已
至于, 你对它的理解, 如果不是等于而是IN的话, 就没有问题了

使用道具 举报

回复
论坛徽章:
22
授权会员
日期:2005-10-30 17:05:332012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:36马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:36
19#
发表于 2004-1-28 21:55 | 只看该作者
最初由 lodge 发布
[B]恩, 有些笔误, 应该是这样
select distinct a.* from exam_score a, (select id, class, max(exam_date) exam_date from exam_score group by id, class) b
where a.id=b.id and a.class=b.class and a.exam_date=b.exam_date

如果你研究一下执行计划, 就会发现, 二者的执行计划几乎一样 [/B]


呵呵,明白你意思,好不容易抓住你的小辫子
执行计划是一样的。

不过还是出现了笔误,应该这样
select distinct a.* from exam_score a, (select id,class,[/COLOR]max(exam_date) exam_date from exam_score group by id, class) b
where a.id=b.id and a.class=b.class and a.exam_date=b.exam_date

使用道具 举报

回复
论坛徽章:
59
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41灰彻蛋
日期:2011-10-28 14:15:35管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-02-18 11:43:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
20#
发表于 2004-1-28 21:58 | 只看该作者
嘿嘿, 刚刚改过来勒

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表