用户
 找回密码
 入住 CI 中国社区
搜索
查看: 3957|回复: 9
收起左侧

数据库Active Record 类 join 方法的问题

[复制链接]
发表于 2012-8-13 14:50:20 | 显示全部楼层 |阅读模式
举个简单的例子,如果我希望有下面这种用法

this->db->from('A');
$this->db->join('B', 'B.xxx = 2 and B.id = A.id', 'left');


意看join的第二个参数,【 B.xxx = 2 】
这里是查表B的一个附加条件,但是在AR类中生成的代码会导致2不被理解为数值:
该代码将会产生

SELECT * FROM (`A`) LEFT JOIN `B` ON `B`.`xxx` = `2` and B.id = A.id

不知道大家注意到了么,这个join的第二个参数第一个 “=” 两边的信息都被理解为“表”和“列”,因而被强行加上了“``”符号,直接导致这个句子出现语法错误。这是问题之一。
然后还请注意到后面绿色标记的部分,等号前后反而没有被添加“``”符号,这是否会存在着一些错误的可能?比如列是系统的某些关键字。
觉得这个地方当属一个BUG,join方法不应该提供第二个参数,而应该像where方法一样,把ON单独列出,比如创建一个方法join_on,这样就不会出现上面所描述的问题。

发表于 2012-8-13 15:57:02 | 显示全部楼层
你单独再加个where可以么
 楼主| 发表于 2012-8-13 16:11:20 | 显示全部楼层
kissgxd 发表于 2012-8-13 15:57
你单独再加个where可以么

我之前的确是这样考虑的,但实际上join on和where的意义是不相同的。
比如
A表为
id    info
1    a
2    b
3    c
B表为
id    xxx
1     2
2     2
3     1

如果把附加条件B.xxx = 2放在join on中,(查询的WHERE 为 A.id = 3)查询的结果集应该是:
id    info    xxx
3     c     NULL
而如果是放在WHERE中,(当前WHERE为 A.id = 3 and B.xxx = 2),则查询的结果集应为空集。
这是两个不同的查询意义,不能这样转换

发表于 2012-8-13 17:41:48 | 显示全部楼层
On 后面 只能 a.xx = b.xx 吧。不能有别的条件了,如果有别的条件的话就是使用where了

SELECT * FROM (`A`) LEFT JOIN `B` ON B.id = A.id WHERE `B`.`xxx` = `2`;

$this->db->from('A');
$this->db->join('B', 'B.id = A.id', 'left');
$this->db->where('B.xxx', 2);

我是如此理解的
发表于 2012-8-13 18:34:32 | 显示全部楼层
Blueve 发表于 2012-8-13 16:11
我之前的确是这样考虑的,但实际上join on和where的意义是不相同的。
比如
A表为

我的想法是和“板凳”相同的
 楼主| 发表于 2012-8-13 19:16:57 | 显示全部楼层
^淡如清风 发表于 2012-8-13 17:41
On 后面 只能 a.xx = b.xx 吧。不能有别的条件了,如果有别的条件的话就是使用where了

SELECT * FROM (`A` ...

我之所以要这样做的目的是要求:
表A中符合WHERE条件(id = ?)的行都要在结果集中出现,如果把B.xxx = ?放到WHERE中,就不符合我的要求了。
至于你所说的只能跟一个条件,不能有别的条件,这个我不大清楚。在网上稍稍查找了一些文章:
http://blog.csdn.net/muxiaoshan/article/details/7617533
发现ON后面跟的条件数目并没有明确的限制(执行的时候也是符合语法规则的),而且也确实有ON 多个条件的用法(上个链接中就出现过)
不知道能否告知这个不能再跟附加条件是否在相关的定义中有规定?如果本身没有作这样的规定(而且就使用来讲,ON多个条件也有合理性吧?),那么AR类的join就理应考虑这样的情形吧
 楼主| 发表于 2012-8-22 13:51:49 | 显示全部楼层
这个……石沉大海了么- -
发表于 2012-8-22 21:32:53 | 显示全部楼层
join 的条件 是建立在 on 的基础上的
所以这里默认是  a.field1 = b.field2  
如果是   a.fieldn = ***
直接在后面用 where 就好了
请好好看看join的含义哦
发表于 2012-8-25 10:55:54 | 显示全部楼层
复杂的查询用这个吧:http://codeigniter.org.cn/user_guide/database/queries.html
不用Active Record 类

要注意字段和表的转义
发表于 2012-8-28 16:20:56 | 显示全部楼层
http://www.oschina.net/question/89964_65912?from=20120826
关于 MySQL LEFT JOIN 你可能需要了解的三点

即使你认为自己已对 MySQL 的 LEFT JOIN 理解深刻,但我敢打赌,这篇文章肯定能让你学会点东西!

    ON 子句与 WHERE 子句的不同
    一种更好地理解带有 WHERE ... IS NULL 子句的复杂匹配条件的简单方法
    Matching-Conditions 与 Where-conditions 的不同

这篇文章估计对你有些帮助,看了后还真很有收获

本版积分规则