MySQL从第二行选择

时间:2013-08-15 14:16:05

标签: mysql

我有三张包含书籍和标签的表格。一本书可以用几个标签标记。

我想要做的是过滤掉用'漫画'和'浪漫'标记的书籍。

  1. 第一本书只标有'漫画'。
  2. 第二本书标有'漫画'和'浪漫',所以这一行应该在我们的例子中返回。
  3. 第三本书仅标有'幻想'。
  4. 如何构建正确的查询以查找第二本书?

      

    ..从书籍b,标签t,tags_to_books tb中选择book_id((查找   TAGS_ID'7'和'8'))..

    表设计:

    DROP TABLE IF EXISTS `books`;
    CREATE TABLE `books` (
      `book_id` int(11) NOT NULL AUTO_INCREMENT,
       PRIMARY KEY (`book_id`)
     );
    
     INSERT INTO `books` (`book_id`)
     VALUES
    (1),
    (2),
    (3);
    
     DROP TABLE IF EXISTS `tags`;
     CREATE TABLE `tags` (
       `tag_id` int(11) NOT NULL AUTO_INCREMENT,
       `tag_name` varchar(11) NOT NULL DEFAULT '',
       PRIMARY KEY (`tag_id`)
     );
    
     INSERT INTO `tags` (`tag_id`, `tag_name`)
     VALUES
    (7,'Comics'),
    (8,'Romance'),
    (9,'Fantasy');
    
     DROP TABLE IF EXISTS `tags_to_books`;
     CREATE TABLE `tags_to_books` (
       `book_id` int(11) NOT NULL,
       `tag_id` int(11) NOT NULL
     );
    
     INSERT INTO `tags_to_books` (`book_id`, `tag_id`)
     VALUES
    (1,7),
    (2,7),
    (2,8),
    (3,9);
    

5 个答案:

答案 0 :(得分:2)

您可以使用类似这样的东西,它实际上与其他SQL语言中的交集运算符相同:

select comics.book_id from (
select b.book_id
  from books b
  join tags_to_books tb on tb.book_id = b.book_id
  join tags t on tb.tag_id = t.tag_id
  where t.tag_id = 7) as comics
join (
select b.book_id
  from books b
  join tags_to_books tb on tb.book_id = b.book_id
  join tags t on tb.tag_id = t.tag_id
  where t.tag_id = 8) as romance
on comics.book_id = romance.book_id

这可能会稍微优化一下,但想法是获取幻想中的所有书籍,然后是所有浪漫的书籍,然后归还两者中的书籍。如果您需要创建需要更多条件的查询,则只需复制JOIN子句并更新标记ID。

Link to SQL fiddle

答案 1 :(得分:1)

如果我理解正确,同一本书可以多次出现在标签表中。正确的吗?

你有没有试过像

这样的东西
SELECT book_id
FROM books
WHERE book_id NOT IN 
    (SELECT comics.book_id
    FROM tags_to_books as comics
    JOIN tags_to_books as romance
      ON comics.book_id = romance.book_id
    WHERE comics.tag_id = 7
      AND romance.tag_id = 8)

答案 2 :(得分:0)

很难读懂但是:

SELECT B.book_id
FROM Books B INNER JOIN tags_to_books ttb
ON ttb.book_ID = b.book_ID
JOIN tags t
ON t.tag_ID = ttb.Tag_ID
WHERE t.tag_ID IN(7) AND t.tag_ID IN(8)

我没有编译过这个但它应该可以工作

如Joe所述,您可以通过tag_name

执行此操作
SELECT B.book_id
FROM Books B INNER JOIN tags_to_books ttb
ON ttb.book_ID = b.book_ID
JOIN tags t
ON t.tag_ID = ttb.Tag_ID
WHERE t.tag_name = 'Comics' AND t.tag_name = 'Romance'

答案 3 :(得分:0)

如果您只需要book_id(而不是书籍的名称或标签的文字,则可行(但如果您的标签数量不同,则需要更改下面描述的幻数)在您的查询中):

SELECT book_id FROM tags_to_books
WHERE tag_id IN (7, 8)
GROUP BY book_id
HAVING COUNT(DISTINCT book_id, tag_id) = 2;

2是标记的数量,如果您的查询中有更多或更少的标记,则必须更改这些标记。

答案 4 :(得分:0)

这是sql:http://sqlfiddle.com/#!2/fc556/6 希望这有帮助