代码之家  ›  专栏  ›  技术社区  ›  Bill H

在mysql中查询多对多表的帮助

  •  0
  • Bill H  · 技术社区  · 15 年前

    我正在尝试获取一个没有特定颜色的产品id列表(数据库是mysql)

    product
    +------------+-------------+
    | product_id | description |
    +------------+-------------+
    |          1 | Widget 1    |
    |          2 | Widget 2    |
    |          3 | Widget 3    |
    |          4 | Widget 4    |
    |          5 | Widget 5    |
    |          6 | Widget 6    |
    +------------+-------------+
    
    color
    +----------+-------+
    | color_id | name  |
    +----------+-------+
    |        1 | red   |
    |        2 | black |
    |        3 | white |
    |        4 | green |
    |        5 | blue  |
    |        6 | pink  |
    +----------+-------+
    
    product_color
    +------------+----------+
    | product_id | color_id |
    +------------+----------+
    |          1 | 1        |
    |          1 | 4        |
    |          1 | 5        |
    |          2 | 2        |
    |          2 | 3        |
    |          3 | 1        |
    |          3 | 2        |
    |          3 | 3        |
    |          5 | 3        |
    |          5 | 6        |
    |          6 | 1        |
    |          6 | 5        |
    |          6 | 6        |
    +------------+----------+
    

    我能做的最好的事情就是:

    SELECT product.*, GROUP_CONCAT(product_color.color_id) as color_ids
    FROM product
    LEFT JOIN product_color USING (product_id)
    GROUP BY product.product_id
    

    这是我的结果集:

    --------------------------------------
    product_id  description     color_ids
    --------------------------------------
    1            Widget 1        1,4,5
    2            Widget 2        2,3
    3            Widget 3        1,2,3
    4            Widget 4        NULL
    5            Widget 5        3,6
    6            Widget 6        1,3,6
    

    然后我以编程的方式过滤它们,但是如果可以的话,我更希望数据库能够完成所有的工作。

    最理想的情况是,我希望我的结果集看起来像这样(我只需要产品id)。

    ------------
    product_id 
    ------------
    2 
    3 
    4 
    

    这是模式和数据的情况下,你的善良的灵魂想帮助我。

    CREATE TABLE IF NOT EXISTS `color` (
      `color_id` int(10) unsigned NOT NULL auto_increment,
      `name` varchar(25) NOT NULL,
      PRIMARY KEY  (`color_id`),
      UNIQUE KEY `name` (`name`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
    
    INSERT INTO `color` (`color_id`, `name`) VALUES
    (2, 'black'),
    (5, 'blue'),
    (4, 'green'),
    (6, 'pink'),
    (1, 'red'),
    (3, 'white');
    
    CREATE TABLE IF NOT EXISTS `product` (
      `product_id` int(10) unsigned NOT NULL auto_increment,
      `description` varchar(25) NOT NULL,
      PRIMARY KEY  (`product_id`),
      UNIQUE KEY `description` (`description`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
    
    INSERT INTO `product` (`product_id`, `description`) VALUES
    (1, 'Widget 1'),
    (2, 'Widget 2'),
    (3, 'Widget 3'),
    (4, 'Widget 4'),
    (5, 'Widget 5'),
    (6, 'Widget 6');
    
    CREATE TABLE IF NOT EXISTS `product_color` (
      `product_id` int(10) unsigned NOT NULL,
      `color_id` int(10) unsigned NOT NULL,
      PRIMARY KEY  (`product_id`,`color_id`),
      KEY `color_id` (`color_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    INSERT INTO `product_color` (`product_id`, `color_id`) VALUES
    (1, 1),
    (3, 1),
    (6, 1),
    (2, 2),
    (3, 2),
    (2, 3),
    (3, 3),
    (5, 3),
    (1, 4),
    (1, 5),
    (6, 5),
    (5, 6),
    (6, 6);
    
    1 回复  |  直到 15 年前
        1
  •  2
  •   JonVD    15 年前

    我认为where子句中的子查询就足够了。

    SELECT DISTINCT product_id 
    FROM product  
    WHERE product_id NOT IN (SELECT product_id FROM product_color WHERE color_id IN (4, 5, 6));