权宜之计002:晕了吧唧的OUTER JOIN

2024-01-09 15:32

本文主要是介绍权宜之计002:晕了吧唧的OUTER JOIN,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Technorati 标签: outer join, Jet SQL, ACCESS, 参数查询

版权声明:可以任意转载,转载时请务必以超链接形式标明如下文章原始出处和作者信息及本声明

作者:xixi

出处:http://blog.csdn.net/slowgrace/archive/2008/10/05/3016635.aspx

 

话说我在ACCESS中写了个这样的嵌套join:

  1. SELECT Sum(tblRecipe_Food.sngNutQuant) AS sngNutQuant之总计, tblNutStan.IDnutStan, tblNutStan.txtNutName
  2. FROM tblMeal INNER JOIN (tblRecipe_Food INNER JOIN (tblFood RIGHT JOIN tblNutStan
  3. ON tblFood.lngNutTypeId = tblNutStan.IDnutStan)
  4. ON tblRecipe_Food.lngFoodId = tblFood.IDfood)
  5. ON tblMeal.lngRecipeId = tblRecipe_Food.lngRecipeID 
  6. GROUP BY tblNutStan.IDnutStan, tblNutStan.txtNutName, tblMeal.dateMeal
  7. HAVING (((tblMeal.dateMeal)=#10/6/2008#));

点击数据表视图,报错提示“不支持连接表达式”。如果把最后的right join改成 inner join,就不报错。问题是我想要把tblNutStan表里的所有记录都检索出来,不管是否在tblFood里是否有相关联的记录,所以我还必须得用RIGHT JOIN.

该查询的设计视图

上面的SQL语句一堆不好看,我把ACCESS里对应的设计视图贴在上面,注意左边2个表之间的箭头方向表示了一个右链接。这个视图上再点击数据表视图,报错:“由于SQL语句中含有二义性的外部连接,所以不能执行。若先强迫执行其中之一个连接,请再创建一个的查询执行第一个连接,然后将该查询包含在SQL语句中。”

看了这个提示,我决定拆成2个查询试试,先写一个这样的查询:

  1. SELECT tblFood.lngNutTypeId, tblRecipe_Food.sngNutQuant
  2. FROM tblMeal INNER JOIN (tblRecipe_Food INNER JOIN tblFood ON tblRecipe_Food.lngFoodId=tblFood.IDfood) ON tblMeal.lngRecipeId=tblRecipe_Food.lngRecipeID
  3. WHERE (((tblMeal.dateMeal)=#10/7/2008#));
命名为zzqryDayPrmFoodNutQuan。对应的设计视图是这样的:

子查询设计视图

然后基于这个查询再做outer join:

  1. SELECT tblNutStan.txtNutName, tblNutStan.lngMin, tblNutStan.lngMax, Sum(zzqryDayPrmFoodNutQuan.sngNutQuant) AS sngNutQuant之总计
  2. FROM tblNutStan LEFT JOIN zzqryDayPrmFoodNutQuan ON tblNutStan.IDnutStan = zzqryDayPrmFoodNutQuan.lngNutTypeId
  3. GROUP BY tblNutStan.txtNutName, tblNutStan.lngMin, tblNutStan.lngMax, tblNutStan.IDnutStan
  4. ORDER BY tblNutStan.IDnutStan;

对应的设计视图是这样的:

基于子查询的查询

这回成了,具体为嘛行了,我也晕了吧唧的。也不是一下就成的,期间试过好几次换子查询的字段,记得主要是总计字段和条件字段换来换去的。这样好了之后,我就高高兴兴的想着怎么把这SQL语句写到代码里。我在代码里,要实时的得到一个日期,替换上面的#2008-10-07#。这可愁坏我了,我不知道该怎么写一个基于动态生成的记录集的查询。因为SELECT语句都是要从数据库里已经存储的对象来找数据的,我估计得先把第一个查询的结果生成一个临时表,然后再left join这个临时表,这些我都不是很熟悉,想想就头大。可能还可以用带参数的存储过程,可我也忘得差不多了。

于是最后我这么做的:我先生成一个动态的recordset,统计得到要outer join的那部分数据;然后把这个记录集的数据(1个字段)逐条复制到要显示所有记录的tblNutStan表的一个字段中;最后用基于tblNutStan表的窗体显示了所有记录。其实我一开始就想这么做,这么做涉及的所有环节我都很熟悉,很快就能折腾出来。只是当时突然冒出一个美好愿望,希望一个查询解决全部问题,就试啊试啊,累死了,最后美好希望还是泡汤了。这会儿忽然想起上学时老师讲join语句的时候我在打瞌睡的事了。唉,搁今天听这课,估计我不会睡哈:~(

P.S. 在Tiger_Zhao的帮助下,最终解决了这个问题。不过,因为程序已经按上面的笨办法测试好了,懒得再折腾了,所以把办法记录在这里。要点包括两个:

  1. 在供外连接的那个子查询里,就是zzqryDayPrmFoodNutQuan了,不带参数,就是不把dateMeal作为条件字段,而作为分组字段,这样,zzqryDayPrmFoodNutQuan就不是一个带参数的查询了,而是一个在数据库里存好的不带参数的对象。这个查询实质上是把所有天的记录都查出来了。
  2. 在外连接里以zzqryDayPrmFoodNutQuan的dateMeal字段作为left join的连接条件。

现在zzqryDayPrmFoodNutQuan的设计视图是这样的:

zzqryDayPrmFoodNutQuan

SQL语句是这样的:

  1. SELECT tblFood.lngNutTypeId, Sum(tblRecipe_Food!sngQuantity*tblFood!sngUnitNutQuant) AS sngNutQuantSum, tblMeal.dateMeal 
  2. FROM tblFood INNER JOIN (tblMeal INNER JOIN tblRecipe_Food ON tblMeal.lngRecipeId = tblRecipe_Food.lngRecipeID) ON tblFood.IDfood = tblRecipe_Food.lngFoodId 
  3. GROUP BY tblFood.lngNutTypeId, tblMeal.dateMeal;

zzNutAnna的SQL语句是这样的(注意加黑的这一不烦):

  1. SELECT tblNutStan.txtNutName, tblNutStan.lngMin, tblNutStan.lngMax, zzqryDayPrmFoodNutQuan.sngNutQuantSum 
  2. FROM tblNutStan LEFT JOIN zzqryDayPrmFoodNutQuan ON ((tblNutStan.IDnutStan = zzqryDayPrmFoodNutQuan.lngNutTypeId) AND (((zzqryDayPrmFoodNutQuan.dateMeal)=#10/9/2008#))) 
  3. GROUP BY tblNutStan.txtNutName, tblNutStan.lngMin, tblNutStan.lngMax, zzqryDayPrmFoodNutQuan.sngNutQuantSum, tblNutStan.IDnutStan 
  4. ORDER BY tblNutStan.IDnutStan;

zzNutAnna的设计视图不能贴出来,因为虽然它能查询出正确的结果,但是系统说现在这个查询不能在设计视图中显示;而我存盘之后干脆再打开这个查询,效果就更诧异了。它会闪一下正确的查询结果,然后报错“不支持连接表达式”,然后就关闭。所以事实上我现在再也打不开这个查询了,幸亏我先把它拷在这个博文里了。所以,这个办法是否能在代码里奏效,我其实还不是很有谱,以后遇到再说吧。

这篇关于权宜之计002:晕了吧唧的OUTER JOIN的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/587598

相关文章

JavaSE-易错题集-002

1. 下面有关java基本类型的默认值和取值范围,说法错误的是? A 字节型的类型默认值是0,取值范围是-2^7—2^7-1 B boolean类型默认值是false,取值范围是true\false C 字符型类型默认是0,取值范围是-2^15 —2^15-1 D long类型默认是0,取值范围是-2^63—2^63-1 答案:C 题解:注意字符型(char) char 占16位,

MySQL学习笔记-join语句类型

join从句的类型:内链接(inner) 全外连接(full outer) 左外连接(left outer) 右外连接(right outer) 交叉链接(cross) 连接条件:使用ON设定连接条件,也可以用WHERE代替 · ON:设定连接条件 · WHERE:进行结果集记录的过滤 一,内连接inner join:  内连接是返回左表及右表符合连接条件的记录,在MySQL中JO

多线程 | join方法

文章目录 1. 作用2. 用法3. 异常4. 源码为什么使用wait方法 5. 如何实现按照指定顺序执行线程6. 线程运行状态 1. 作用 在 Java 多线程中,join方法用于等待一个线程执行完毕。当一个线程调用另一个线程的join方法时,当前线程会进入等待状态,直到被调用的线程执行完毕。这使得开发者可以控制线程的执行顺序,确保某些关键线程在其他线程之前完成执行。 2. 用

SylixOS pthread_join退出

1 问题描述 在移植中间件过程中,在SylixOS下调用pthread_join时,如果线程在pthread_join等待之前结束,则线程返回无效线程错误值。在Linux下这种调用会正常返回。两种实现是有差别的,实现的原理分别如下。 2 函数实现机制 2.1 实现机制 在SylixOS下调用pthread_join时,如果线程在pthread_join等待之前结束,线程返回无效线程错误标志

多表连接的三种方式hash join,merge join,nested loop

多表之间的连接有三种方式:Nested Loops,Hash Join和 Sort Merge Join. 下面来介绍三种不同连接的不同:     一. NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择。在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大(大于1 万不适合),要把返回

Apache-Flink深度解析-Temporal-Table-JOIN

在《JOIN LATERAL》中提到了Temporal Table JOIN,本篇就向大家详细介绍什么是Temporal Table JOIN。在ANSI-SQL 2011 中提出了Temporal 的概念,Oracle,SQLServer,DB2等大的数据库厂商也先后实现了这个标准。Temporal Table记录了历史上任何时间点所有的数据改动,Temporal Table的工作流程如下:

​​NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南002

继续,执行pom.xml引入依赖以后,发现以下几种报错: 可以看到在下载aws-java-sdk-bundle 1.12.710版本的时候报错了 可以看到日志信息,就是在阿里云上下载的,因为阿里云上缺少这个jar包 aws-java-sdk-bundle-1.12.710.jar 这个jar包,我还特意去阿里云上查询了一下 https://developer.aliyun.com/

Flink重点难点:维表关联理论和Join实战

点击上方蓝色字体,选择“设为星标” 回复”面试“获取更多惊喜 在阅读本文之前,你应该阅读过的系列: 《Flink重点难点:时间、窗口和流Join》《Flink重点难点:网络流控和反压》 Flink官方文档中公开的信息 1 Join 的概念 在阅读之前请一定要先了解: 数据流操作的另一个常见需求是对两条数据流中的事件进行联结(connect)或Join。Flink DataStream API中

【硬刚Hadoop】HADOOP MAPREDUCE(11):Join应用

本文是对《【硬刚大数据之学习路线篇】从零到大数据专家的学习指南(全面升级版)》的Hadoop部分补充。 1 Reduce Join Map端的主要工作:为来自不同表或文件的key/value对,打标签以区别不同来源的记录。然后用连接字段作为key,其余部分和新加的标志作为value,最后进行输出。 Reduce端的主要工作:在Reduce端以连接字段作为key的分组已经完成,我们只需要在

java join sleep wait notify notifyAll

sleep:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。  通过调用sleep使任务进入休眠状态,在这种情况下,任务在指定的时间内不会运行。 调用sleep的时候锁并没有被释放。 休眠  Java SE5引入了更加显示的sleep()版本作为TimeUnit类的一部分,这个方法允许你