我需要帮助编写一个复杂的(对我来说)SELECT语句

时间:2010-06-24 18:12:33

标签: sql mysql

确定。我是MySQL的新手有一个SELECT语句,我无法解决这个问题。

我有一张带有ASIN主键(10位ISBN)的书籍表,我有一张带有自动递增主键的标签表。然后我有一个联结表来显示哪些ASIN具有与之关联的标签。

我可以使用此SELECT语句为任何书籍使用单个标记:

SELECT b.asin, b.title, b.img_thumb, b.filename FROM books AS b
INNER JOIN tag_junction AS tj USING (asin)
WHERE tj.tag_id=14 
ORDER BY title

但我想做的是编写一个查询,通过AND和OR,为任何包含多个标签的书籍提供。我试过写下面的内容如下,但这不起作用。

SELECT b.asin, b.title, b.img_thumb, b.filename FROM books AS b
INNER JOIN tag_junction AS tj USING (asin)
WHERE tj.tag_id=14 AND tj.tag_id=12 
ORDER BY title

所以基本上我希望查询返回任何同时使用tag_id 14和tag_id 12的书籍。我也希望能够查询使用14 OR 12的书籍。

我错过了什么?

6 个答案:

答案 0 :(得分:3)

使用:

SELECT b.asin, 
       b.title, 
       b.img_thumb, 
       b.filename 
  FROM BOOKS b
  JOIN TAG_JUNCTION tj ON tj.asin = b.asin
 WHERE tj.tag_id IN (12, 14)

这将返回与以下内容关联的BOOKS记录:

  • tag_id 12
  • tag_id 14
  • tag_id 12和tag_id 14
  • 的组合

只要其中一个满意,就会返回相关的BOOKS记录。

要返回所有标记匹配的位置,您必须添加GROUP BY和HAVING子句:

SELECT b.asin, 
       b.title, 
       b.img_thumb, 
       b.filename 
  FROM BOOKS b
  JOIN TAG_JUNCTION tj ON tj.asin = b.asin
 WHERE tj.tag_id IN (12, 14)
GROUP BY b.asin, b.title, b.img_thumb, b.filename 
  HAVING COUNT(DISTINCT tj.tag_id) = 2

HAVING子句中的计数数 必须匹配 IN子句中指定的标签数。

答案 1 :(得分:1)

这样做应该会给你三种情况:

SELECT b.asin, b.title, b.img_thumb, b.filename FROM books AS b
INNER JOIN tag_junction AS tj USING (asin)
WHERE (tj.tag_id=14 OR tj.tag_id=12) ORDER BY title

具有14 AND 12的书籍也符合具有14 OR 12的书籍的标准:o)

答案 2 :(得分:0)

除非另有说明,否则总结别人所说的内容,或者是包容性的。您会发现,在Computerland中,编程和脚本语言,CPU级别的按位操作以及硬件级别的门逻辑都是如此。它也是逻辑(哲学)中的这种方式。

要成为ANDs和OR以及其他逻辑事物的高手,请查看真值表:http://en.wikipedia.org/wiki/Truth_table

答案 3 :(得分:0)

要匹配这两个标记,只需使用已发布的已修改查询版本。使用相同的查询进行过滤,另外检查给定书籍的标签是否等于2 - 这可以确保两者都匹配。

SELECT b.asin, b.title, b.img_thumb, b.filename 
FROM books b
JOIN tag_junction tj ON tj.asin = b.asin
WHERE tj.tag_id IN (12, 14)
AND 
( 
  SELECT COUNT(*) 
  FROM books ib 
  JOIN tag_junction itj ON (itj.asin = ib.asin)
  WHERE itj.tag_id IN (12, 14) AND ib.asin = b.asin
) = 2
GROUP BY b.asin
ORDER BY title

答案 4 :(得分:0)

这适用于您的AND案例。请注意,硬编码2必须与IN子句中的ID数相匹配:

select *
from books 
where asin in (
    SELECT b.asin
    FROM books b
    INNER JOIN tag_junction tj on b.asin = tj.asin
    WHERE tj.tag_id in (12, 14)
    group by b.asin
    having count(distinct tj.tag_id) = 2
)

对于您的OR案例,您可以这样做:

SELECT b.asin, b.title, b.img_thumb, b.filename
FROM books AS b
INNER JOIN tag_junction tj on b.asin = tj.asin
WHERE tj.tag_id in (12, 14)

答案 5 :(得分:0)

使用distinct:

SELECT distinct b.asin, b.title, b.img_thumb, b.filename  
FROM books b 
JOIN tag_junction tj ON tj.asin = b.asin 
WHERE tj.tag_id IN (12, 14) 
AND  
(  
  SELECT COUNT(*)  
  FROM books ib  
  JOIN tag_junction itj ON (itj.asin = ib.asin) 
  WHERE itj.tag_id IN (12, 14) AND ib.asin = b.asin 
) = 2 
GROUP BY b.asin 
ORDER BY title