MySQL:仅当IN()中的所有值与结果

时间:2017-09-29 12:42:11

标签: mysql joomla tags

解决方案

查询

SELECT a.introtext FROM ( SELECT b.content_item_id as id,COUNT(DISTINCT b.tag_id) as rc FROM `#__contentitem_tag_map` AS `b` INNER JOIN `#__tags` AS `c` ON (`b`.`tag_id` = `c`.`id`) WHERE `c`.`alias` IN ("") GROUP BY `b`.`content_item_id`)f INNER JOIN `#__content` AS `a` ON (`a`.`id` = `f`.`id`) INNER JOIN `#__contentitem_tag_map` AS `b` ON (`a`.`id` = `b`.`content_item_id`) INNER JOIN `#__tags` AS `c` ON (`b`.`tag_id` = `c`.`id`) WHERE `c`.`alias` IN ("") AND `a`.`state` = 1 AND `c`.`level` > 0 AND `c`.`published` = 1 AND `a`.`catid` = 27 AND `f`.`rc` = 1 GROUP BY `a`.`id` ORDER BY a.title ASC

Joomla SQL

这是自定义模块中的Joomla SQL

// Create a new query object.
$subQuery = $db->getQuery(true);
$query = $db->getQuery(true);

$tags = array('facebook','html5');
$count = count($tags);
$tags = '"' . implode('","',$tags) . '"';

$subQuery

->select(array('b.content_item_id as id','COUNT(DISTINCT b.tag_id) as rc'))

->from($db->quoteName('#__contentitem_tag_map','b'))

->join('INNER', $db->quoteName('#__tags', 'c') . ' ON (' . $db->quoteName('b.tag_id') . ' = ' . $db->quoteName('c.id') . ')')

->where(($db->quoteName('c.alias') . ' IN ('.$tags.')'))

->group($db->quoteName('b.content_item_id'));

$query

->select(array('a.introtext'))

->from('('.$subQuery.')f')

->join('INNER', $db->quoteName('#__content', 'a') . ' ON (' . $db->quoteName('a.id') . ' = ' . $db->quoteName('f.id') . ')')

->join('INNER', $db->quoteName('#__contentitem_tag_map', 'b') . ' ON (' . $db->quoteName('a.id') . ' = ' . $db->quoteName('b.content_item_id') . ')')

->join('INNER', $db->quoteName('#__tags', 'c') . ' ON (' . $db->quoteName('b.tag_id') . ' = ' . $db->quoteName('c.id') . ')')

->where(($db->quoteName('c.alias') . ' IN ('.$tags.')'), 'AND')

->where(($db->quoteName('f.rc') . ' = ' . $count))

->group($db->quoteName('a.id'))

->order('a.title ASC');

我正在使用 MySQL 以及 Joomla的内容! 3.8数据库

正在使用的表格

  • #__含量
  • #__ contentitem_tag_map
  • #__标签

故事

我使用开发人员的个人资料创建了文章。每个开发人员都可以使用" jQuery"," html5"等技能标记他/她自己。 这些技能作为标签存储在#__tags表中。

我尝试从#content表中选择与我正在搜索的标签匹配的所有开发人员。

例如,我正在寻找一个开发者,他可以做HTML5'以及' JavaScript'。

结果应该是空的,因为有一个单独的开发用于HTML5' &安培; ' CSS3'另一个开发者用于' CSS3'只在我的数据库中。

丑陋的事实

正在搜索HTML5'和' Javascript'返回1个结果。

应该是

的方式

正在搜索HTML5'和' Javascript'应该返回0结果,因为没有具有这两种技能的开发。

查询

SELECT
a.id as id,
a.title,
c.id as tag_id,
c.alias as tag_alias
FROM `#__content` as `a`
INNER JOIN `#__contentitem_tag_map` AS b ON (a.id = b.content_item_id) 
INNER JOIN `#__tags` AS c ON (b.tag_id = c.id)
WHERE c.alias IN ('html5','javascript')

id | title | tag_id | tag_alias
-------------------------------
22 | xyz   |      6 | html5

问题

怎么办?顺便说一下,我不能使用像HAVING COUNT(\*) = x;这样的东西,因为多个标签会有多个结果。

感谢您的支持! < 3

其他信息

使用HAVING COUNT(\*) = x(其中x是使用的标签数量)仅返回1个开发人员/标签,而不是每个具有此特定标签的开发人员。

SQL Fiddle

http://sqlfiddle.com/#!9/f5cb6f/2

1 个答案:

答案 0 :(得分:1)

我试图为你的问题找到一个解决方案(我不确定查询是不是更好;我不太喜欢我必须重复两次条件c.alias IN('html5','javascript' ))。

也许这对你来说并不重要,但是这个查询可以在除了Mysql之外的其他数据库引擎上使用(例如MSSQL),因为它不使用GROUP_CONCAT或“permissive”GROUP BY子句。

查询似乎适用于除2之外的更多值(例如,要检查的三个别名),当然也会改变RC的条件。

在内部部分,它计算表#__contentitem_tag_map中存在的每个标记的(不同)值:因此在外部部分中,查询可以提取具有至少两个的标记(或者在WHERE条件中指定的期望数量RC = xx)存在的值。这允许“模拟”你需要的那种“AND条件”。在外部部分查询进行其他必要的连接以提取所需的列 (在内部部分,如您所见,没有必要使用表#__内容。)

我在您的示例数据中添加了以下数据:

INSERT INTO `#__content` (`id`, `title`) VALUES (29, 'New one');
INSERT INTO `#__contentitem_tag_map` (`content_item_id`, `tag_id`) VALUES (29, 6);
INSERT INTO `#__contentitem_tag_map` (`content_item_id`, `tag_id`) VALUES (29, 1);
INSERT INTO `#__tags` (`id`, `alias`) VALUES (1,'facebook');



SELECT F.ID,
A.title as title,
B.tag_id,
C.alias as tag_alias
FROM (SELECT  b.content_item_id as id,
      COUNT(DISTINCT b.tag_id) AS RC
      FROM `#__contentitem_tag_map` AS b
      INNER JOIN `#__tags` AS c ON b.tag_id = c.id
      WHERE c.alias IN ('html5','facebook')
      GROUP BY b.content_item_id
      ) F
INNER JOIN `#__content` A  ON A.id = F.id
INNER JOIN `#__contentitem_tag_map` B ON a.id = B.content_item_id
INNER JOIN `#__tags` C ON B.tag_id = C.id
WHERE C.alias IN ('html5','facebook')
    AND F.RC=2;
;      

输出:

    ID  title   tag_id  tag_alias
1   29  New one 6   html5
2   29  New one 1   facebook