|
版友chinasa同志在论坛提出了一个关于SQL联接的问题,这个问题比较有趣。其有趣之处在于需要采用一种比较特殊的表达式来处理两表间的联接关系。问题的内容如下:
1.业务表的代码全部是标准的5位代码。
2.合约中的代码可能是5位代码或2位代码,或者任意组合(中间以斜杠分开)。
3.其中2位代码是5位代码的前两位。
需求是:当合约号相同,业务表代码被包含在合约表的代码中,则取合约价格。
就chinasa同志的数据表结构来看,其合约表的代码字段是不符合范式理论的第一范式的,也就是说该字段的一条记录中存在多值。范式理论作为关系数据库的基础,是非常重要的,通常情况下数据表的设计均应该遵循范式。不过过分强调这一点,有可能落入唯范式的陷阱。有时候根据商务逻辑的特点,适度的违反一下范式可能比完全遵循范式在效率上会更高一些。当然,这是在你充分理解范式的基础上,才应该做出的选择。没有这个基础,那就是瞎胡闹胡球搞。本问题的原型无法全面观察,所以不能判断chinasa同志是不是瞎胡闹胡球搞。
暂且不论chinasa同志不论是否瞎胡闹胡球搞。本例想要阐释的是另外一个问题,这个问题事关表联接的处理。写一个两表之间的内联接,对于大多数版友来说并不困难。不过写两表或者多表的联接,大体有三层功夫。这些功夫体现在ON子句的处理上。第一层功夫是说你知道两个表之间一些对应字段用等号表示联接关系;第二层功夫是说你知道两表之间的对应字段不仅可以用等号表示联接关系,还可以用大于、小于等关系运算符表示。
其实,Access的帮助文档只能帮你掌握第二层功夫,因为这个文档对ON子句只解释到用关系运算符联接两个表的对应字段。如果你的大脑还不至于太笨的话,你会知道关系运算符联接字段名,实际上是一个逻辑表达式。那么由此推理,ON子句应该是一个逻辑表达式。不知道你理解了没有,为什么我说要将其理解为逻辑表达式而不是仅仅是关系表达式呢?答案是,逻辑表达式更为广泛。也就是说ON子句不一定写成关系表达式,而可以更广泛的写成逻辑表达式。知道了这一点,你就获得了第三层功夫。
本例中当然是需要第三层功夫。说起来,功夫高,并不意味着功夫复杂。其实只是一个境界而已,进入了这个境界,一切都很简单。本例的写法也不复杂,大体可以这样去写:
SELECT a.*, b.合约价格
FROM 业务表 AS a INNER JOIN 合约表 AS b ON (instr(b.代码,a.业务代码)>0) AND (a.合约号=b.约号);
注意instr(b.代码,a.业务代码)>0,虽然这也是一个关系表达式,但这个关系表达式中b.代码与a.业务代码并不在关系运算符的两侧,所以将这个表达式理解为逻辑表达式更为恰当。这个表达式是表示a.业务代码是否包含在b.代码中。当然表示这个计算的表达式还可以有多种,比如你还可以用StrComp函数来计算。
示例:
视图:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
评分
-
查看全部评分
|