MySQL:仅当 IN() 中的所有值都匹配结果时才返回

标签 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');

我正在使用 MySQLJoomla! 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

最佳答案

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

也许这对您来说并不重要,但此查询也可以用于 Mysql 以外的其他数据库引擎(例如 MSSQL),因为它不使用 GROUP_CONCAT 或“许可的”GROUP BY 子句。

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

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

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

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

关于MySQL:仅当 IN() 中的所有值都匹配结果时才返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46489064/

相关文章:

javascript - 有没有办法创建自己的 HTML 元素?

javascript - 使用Javascript修改内部标签的CSS规则

mysql - MySQL ORDER BY RAND() 函数什么时候排序?

php - MySQL选择有和没有关系的行

mysql - cakephp 分页顺序被忽略

wordpress - Plone 是否足以跟上其他 CMS 的步伐?

android - Arraylist 未正确解析

javascript - 如何将 joomla 表单(在文章中)重定向到不同的 joomla 文章?

php - 如何强制 joomla 仅搜索一个组件数据

javascript - 当脚本代码更改文本时返回输入的 javascript 堆栈跟踪