我在mysql中有3张桌子:
卡片:
id | name
1 | alpha
2 | beta标签:
id | name
1 | a
2 | btag_link:
id | card | id
1 | 1 | 1
2 | 2 | 1
3 | 2 | 2我想取回所有不包括特定标签的卡片。CI模式:
function search($_tag) {
$this->db->select('card.id');
$this->db->join('tag_link', 'card.id = tag_link.card');
$this->db->where_not_in('tag_link.tag', $_tag);
$this->db->group_by('card.id');
$query = $this->db->get('card');
return $query;
}对于标签'2‘,这将返回卡片'1’如预期。然而,卡'2‘也被错误地返回,因为在tag_link连接卡'2’与标签'1‘的一个条目。
我考虑使用上面的函数获得第一个点击数组,然后在php中减去另一个数组,其中包含所有卡片,包括我不感兴趣的标记。然而,这个解决方案感觉非常笨拙。解决这个问题的最有效的方法是什么?
谢谢你,奇图
发布于 2013-10-04 05:18:19
使用TheWolf的答案并将其转换为active_record。记住,CI不支持子查询(尽管可以使用库)。
$this->db->select('id');
$this->db->where('id NOT IN (SELECT card FROM tag_link WHERE tag IN $tags)', NULL, FALSE);
$query = $this->db->get('cards');发布于 2013-10-03 22:48:34
我对CI不太了解,但作为SQL查询,这可能有效(将SQL和php混合在一起的伪代码):
SELECT id
FROM cards
WHERE id NOT IN
(
SELECT card FROM tag_link WHERE tag IN $tags
)子查询返回包含特定标记的所有卡片ids。然后,主查询返回所有其他卡片ids。(请注意,子查询会导致大型表和/或复杂查询中的性能问题)
发布于 2013-10-04 07:23:13
首先,您的表结构应该有明确的名称链接
cards:
-------
id | name
1 | alpha
2 | beta
tags:
------
id | name
1 | a
2 | b
tag_link:
---------
id | card_id | tag_id
1 | 1 | 1
2 | 2 | 1
3 | 2 | 2然后,您可以设置一个和条件,以避免其他结果。并提供避险卡。否则回答问题就没用了。
function search($tag_id,$card_id) {
return $this->db
->select('card.id')
->from('tag_link')
->join('card','card.id = tag_link.card_id','INNER')
->where_not_in('tag_link.tag_id',$_tag)
->where_not_in('tag_link.card_id',$card_id)
->get()
->result_array()
}这将生成此查询。
SELECT
card.id
FROM tag_link
INNER JOIN card
ON card.id = tag_link.card_id
WHERE tag_link.tag_id NOT IN(2)
AND tag_link.card_id NOT IN(2)正如您所看到的,您正在避免卡2,其他明智的,您一定会得到所有的卡是链接到任何身份,无论如何,考虑到较少的tag_id你提供。
这里是用来测试的小提琴
https://stackoverflow.com/questions/19170048
复制相似问题