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

[HELP] 联合查询另一张表中的三条数据,放到一个对象里,怎么办

[复制链接]
发表于 2011-7-20 16:33:40 | 显示全部楼层 |阅读模式
本帖最后由 melkor 于 2011-7-20 16:40 编辑

goods表:
[goods_id] [goods_name] ... [category_id] [category_id_branch] [category_id_top] ...
category表:
[category_id] [category_name] [parent_id]...


goods表中的[category_id] [category_id_branch] [category_id_top]都对应于category表中的category_id字段,也就是说,goods表中的一条数据会记录三个category。
目前要做的是,通过一个$category_id来得到对应goods表中的一组数据,同时得到每条数据中的category_id_branch和category_id_top在category表中的category_name。
一开始,$this->db->join('category', 'category.category_id = goods.category_id')->get_where('goods', array('category_id => $category_id'))->result()可以得到一个对象数组,数组中每个元素都有了category_name这个属性。
但是如果再join了category表就会报错,大概是Not unique table/alias: 'category',想了想也是,三次join的category表,得到的数据字段都是一样的,三个category_name没法儿安排。
如果分别查询三条数据,或者通过parent_id找到branch和top的数据,再合并进对象数组里,那非常麻烦,需要一个大循环什么的,效率很低了。怎么能够做到读取的结果是一个对象数组,每个对象中包含对应的三个category_name(比如分别叫做[category_name] [category_name_branch] [category_name_top])?

直接SQL语句的尝试:
SQL复制代码
[color=#000][font=Tahoma][SIZE=3]SELECT exp_goods.*, c1.category_name AS category_name, c2.category_name AS category_name_branch, c3.category_name AS category_name_top FROM exp_category AS c1, exp_category AS c2, exp_category AS c3 JOIN c1 ON c1.category_id = exp_goods.goods_category_id JOIN c2 ON c2.category_id = exp_goods.goods_category_id_branch JOIN c3 ON c3.category_id = exp_goods.goods_category_id_top[/SIZE][/font][/color]
复制代码

报错:Not unique table/alias: 'c1'


救命……
发表于 2011-7-20 16:46:10 | 显示全部楼层
本帖最后由 jeongee 于 2011-7-20 16:49 编辑

即使做到了,效率也低了点、
你这样的情况建议你缓存分类数据,不必纠结这样的联合查询了或者你分2次查询,
第一次取出good,第二次用in条件去取出分类
发表于 2011-7-20 16:46:12 | 显示全部楼层
SELECT A.*,
       B.CATEGORY_NAME AS CATEGORY_NAME,
       C.CATEGORY_NAME AS CATEGORY_NAME_BRANCH,
       D.CATEGORY_NAME AS CATEGORY_NAME_TOP
  FROM GOODS A, CATEGORY B, CATEGORY C, CATEGORY D
WHERE A.CATEGORY_ID = B.CATEGORY_ID
   AND A.GOODS_CATEGORY_ID_BRANCH = C.CATEGORY_ID
   AND A.GOODS_CATEGORY_ID_TO = D.CATEGORY_ID
发表于 2011-7-20 16:48:01 | 显示全部楼层
pl sql (避免关联不上category id,导致拿不出数据,增加left join):

SELECT A.*,
       B.CATEGORY_NAME AS CATEGORY_NAME,
       C.CATEGORY_NAME AS CATEGORY_NAME_BRANCH,
       D.CATEGORY_NAME AS CATEGORY_NAME_TOP
  FROM GOODS A, CATEGORY B, CATEGORY C, CATEGORY D
WHERE A.CATEGORY_ID = B.CATEGORY_ID
   AND A.GOODS_CATEGORY_ID_BRANCH = C.CATEGORY_ID(+)
   AND A.GOODS_CATEGORY_ID_TO = D.CATEGORY_ID(+)
 楼主| 发表于 2011-7-20 17:36:51 | 显示全部楼层
jeongee 发表于 2011-7-20 16:46
即使做到了,效率也低了点、
你这样的情况建议你缓存分类数据,不必纠结这样的联合查询了或者你分2次查询, ...

那怎么才能将结果组合到一个对象里呢?
发表于 2011-7-20 17:56:49 | 显示全部楼层
melkor 发表于 2011-7-20 17:36
那怎么才能将结果组合到一个对象里呢?

如果是缓存的很好办,加载缓存就能知道id对应的分类了。
如果是我说的2次查询,也好办啊,$good = $this->db->xxxx()->row();
然后你$good->category_names = $this->db->where_in('xx',你自己拼接的条件)->result();
所有的数据都在$good对象里了
 楼主| 发表于 2011-7-20 19:26:52 | 显示全部楼层
jeongee 发表于 2011-7-20 17:56
如果是缓存的很好办,加载缓存就能知道id对应的分类了。
如果是我说的2次查询,也好办啊,$good = $this- ...

但是取出的$goods是个数组,这就意味着需要一个循环……这样的效率和联合查询的比呢?nekchen的方法可行
发表于 2011-7-20 19:28:05 | 显示全部楼层
melkor 发表于 2011-7-20 19:26
但是取出的$goods是个数组,这就意味着需要一个循环……这样的效率和联合查询的比呢?nekchen的方法可行 ...

缓存分类数据
CIer  发表于 2013-4-6 08:39:25
hello, world!

本版积分规则