不算总结的总结:得分者无一例外,都是用字典对象来答题的。 出题出了个大BUG ,类似题目用字典解决论坛中已有多个例子,我自己也给其他会员写过。 所以想当然地忽略了字典,忘记说明 限制使用字典。 呵呵给大家送分了。 遗憾的是么有看到 非ado 非字典的 高效处理方法。 _________________________________________________________________________________________ 介绍一下ado方法 最短语句如下 strSQL = "b left join a on b.nm=a.nm where a.nm is null" 这道题从 strSQL = "select nm from b where nm in (select nm from a)" 取反向值而来。 这个语句运行正常。想当然的既然取反向值 加个 not 就行了 strSQL = "select nm from b where nm not in (select nm from a)" 在编写测试代码时数据量不大,感觉不出问题,随着时间推移数据增加,这个语句运行起来就像死机一样。 这是我给客户编写的一个小程序中的BUG,好在圆满解决了,没让我陪钱。 我们接触的ado语句 90%与 select 语句有关,也就说绝大部分是基于表的操作。 一个select语句可以看作是一个表,同样一个表也可看作是一个 “select * from 表名” 语句 完整的语句应该是这样的(在a、b表都不止一列的情况下) : str1 = "select * from
((select nm from b) as b left join (select nm from a) as a on b.nm=a.nm) where a.nm is null" 这个语句可以这样理解 两个表(绿括号)按条件合并成一个新表,再从新表中安条件提取数据。 红色括号可以省略, left join ..... on 语句 被自动判断为一个 表(语句)并优先处理,在此之前 先处理两个绿括号中的语句。 语句中 as b 和 as a 不能省略,这里的b和a 可以把它当作变量来看, 指代绿括号中的表(语句),只是刚好用了本身的名称, 也可以改为 as c 和 as d 但后面的 on 语句 要相应的改为 c.nm=d.nm 题目中 a 和 b 表都只有一列 所以 select nm from a (或 b) 所返回的都是一个完整的表。 语句可以进一步简化 str2 = "select * from
(b left join a on b.nm=a.nm) where a.nm is null" 这个语句返回两个表(合并后新表)的所有列,共两列 ,红色括号中的语句可以看作一个表 一个select语句可以看作是一个表,同样一个表也可看作是一个 “select * from 表名” 语句 进一步简化 strSQL = "b left join a on b.nm=a.nm where a.nm is null" 但是 像上面的str1 就不能这样简化 str1 = "(select nm from b) as b left join (select nm from a) as a on b.nm=a.nm where a.nm is null" 有关ado的内部运行机制,很难找到相关资料(估计网上是没有的),很多时候只能靠经验来处理了。 如果 a 表和 b表 都不止 一列 ,假设 a表有 30 列 b表有 50 列 strSQL = "b left join a on b.nm=a.nm where a.nm is null" 这个语句 将返回 80 列的 数据(表),如果只需要返回两列,则在前面增加 "select b.nm ,a.nm from " 语句 返回结果和str1 一样,但在效率上来说,str1要高的多 str1 = "select * from
((select nm from b) as b left join (select nm from a) as a on b.nm=a.nm) where a.nm is null" 因为这个语句自始至终 都只返回两列。 所以最简的语句 就是一个表名 像这个语句: Sheets("a").Range("a1").CopyFromRecordset cn.Execute("SELECT * FROM a") 可以直接简化为: Sheets("a").Range("a1").CopyFromRecordset cn.Execute("a") 想表达的意思比较多(帮助文件里是没有的),看起来有点乱。包涵包涵。 希望会员看了此文能对ado的理解有所帮助。 |