如何从标签创建临时表?

时间:2010-09-24 15:22:34

标签: php mysql sql

我有一个product_table,其中包含product_id个字段。

我正在创建一个包含2个字段tag_tabletag_id的{​​{1}}。

标签可以是“银”或“宾州”等等。

我还使用tag_nameproduct_tag_map创建product_id表格,以便将产品映射到任意数量的代码。

如果我想创建一个包含所有标记为“silver”,“necklace”,“diamond”的产品的类别。但也排除任何标记为“初始”,“旅程”的产品

(显然我会使用tag_id而不是tag_name,所以带有标签[2,4,5]的产品没有标签[3,6])

如何创建临时产品表并使用匹配的产品填充它?

更新

这是我的product_tag_map表:

tag_id

注意:我没有使用CREATE TABLE `product_tag_map` ( `product_tag_map_id` int(11) NOT NULL auto_increment, `tag_id` int(11) NOT NULL, `product_id` int(11) NOT NULL, PRIMARY KEY (`product_tag_map_id`), UNIQUE KEY `tag_id` (`tag_id`,`product_id`), KEY `tag_id_2` (`tag_id`) ) ENGINE=MyISAM AUTO_INCREMENT=7897 DEFAULT CHARSET=utf8 。我只是习惯于为每张桌子提供一个主键。所以如果我应该把它删除那么好。

2 个答案:

答案 0 :(得分:1)

问题是,你需要一个临时表 ?为什么不直接查询呢?

SELECT
  p.product_id,
  p.product_name
FROM
  product_table p
WHERE
  EXISTS (
    SELECT 1 
      FROM product_tag_map 
     WHERE product_id = p.product_id AND tag_id IN (2,4,5)
  )
  AND NOT EXISTS (
    SELECT 1 
      FROM product_tag_map 
     WHERE product_id = p.product_id AND tag_id IN (3,6)
  )

创建适当的索引(一个多列索引超过(product_tag_map.product_id, product_tag_map.tag_id),另一个超过(product_tag_map.tag_id),除了“普通”PK / FK索引之外),这应该足够快。


编辑:可缓存(就查询计划而言)以及上述更具动态的变体:

创建一个user_searches(search_session_id, tag_id, include),其中多列索引超过(search_session_id, include),另一个索引超过tag_id。然后在用户选择条件时填写它:

search_session_id   tag_id   include
              ...
             4711        2         1
             4711        4         1
             4711        5         1
             4711        3         0
             4711        6         0
              ...

并且像这样查询:

SELECT
  p.product_id,
  p.product_name
FROM
  product_table p
WHERE
  EXISTS (
    SELECT 1 
      FROM product_tag_map m INNER JOIN user_searches s ON s.tag_id = m.tag_id
     WHERE m.product_id = p.product_id 
           AND s.search_session_id = 4711 /* this should be a parameter */
           AND s.include = 1
  )
  AND NOT EXISTS (
    SELECT 1 
      FROM product_tag_map m INNER JOIN user_searches s ON s.tag_id = m.tag_id
     WHERE m.product_id = p.product_id 
           AND s.search_session_id = 4711 /* this should be a parameter */
           AND s.include = 0

  )

答案 1 :(得分:1)

您可以在select语句上创建视图。

(视图基本上是一个虚拟表,您可以轻松查询,但是可以使用复杂语句中的数据进行查询。阅读本手册,在性能和读/写行为方面并非如此简单。)

但是您的查询可能如下所示:

SELECT 
product_id, count(*) as total 
FROM tag_map WHERE tag_id IN (2,4,5) 
AND total = 3 
AND product_id NOT IN (
SELECT product_id, count(*) as total FROM tag_map WHERE tag_id IN (3,6) 
WHERE total = 2 GROUP BY ( product_id )
)
GROUP BY ( product_id )

你也可以加入,但我认为它会慢一些。