MySQL加入多个表

时间:2013-04-01 10:30:30

标签: mysql sql join

我的网络应用程序需要一个包含所有用户组,组成员以及他们可以根据组成员身份访问的产品列表的列表。

Web应用程序支持多个“站点”;站点是这些用户,组和产品的唯一标识符。

我有以下查询:

SELECT u.id as user_id, u.username, ug.group_id, ug.group_name, u.firstname, u.surname, p.product_name, p.product_id, p.product_price, p.product_currency, p.is_public
    FROM user_groups ug
    LEFT JOIN user_group_users ugu ON ug.group_id = ugu.group_id
    RIGHT JOIN users u ON u.id  = ugu.user_id
    LEFT JOIN user_group_product ugp on ug.group_id = ugp.group_id
    LEFT JOIN product p on p.product_id = ugp.product_id
    WHERE u.site_id = 5
    ORDER BY ug.group_name desc, u.surname, u.firstname, u.username

这很好用,我使用PHP连接结果来传递数据。

问题PRODUCTS表格也有一个is_public标记,我想在结果集中包含所有产品,并将其设置为1作为用户具有组访问权限的返回产品,但同样仅适用于此站点。

因此,为了清楚起见,我希望回复:

  • 所有用户记录 - 无论是否具有组成员身份(将显示未分组用户)
  • 具有关联组成员身份的所有用户记录
  • 所有群组
  • 所有产品 - 用户是该组的成员
  • 所有产品 - 产品设置为公开的产品 - is_public = 1

上述所有内容必须仅适用于相关网站。

更新3 :更新了要求说明

更新2 :表格结构:

--
-- Table structure for table `user_group_users`
--

CREATE TABLE IF NOT EXISTS `user_group_users` (
  `user_group_id` bigint(20) unsigned NOT NULL auto_increment,
  `user_id` mediumint(9) NOT NULL default '0',
  `group_id` mediumint(9) NOT NULL default '0',
  `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`user_group_id`),
  KEY `user_id` (`user_id`,`group_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=54 ;

--
-- Table structure for table `user_groups`
--

CREATE TABLE IF NOT EXISTS `user_groups` (
  `group_id` mediumint(8) unsigned NOT NULL auto_increment,
  `site_id` mediumint(9) NOT NULL,
  `group_name` varchar(100) NOT NULL default '',
  `is_default` tinyint(1) NOT NULL COMMENT 'Users are automatically added to default groups at registration',
  PRIMARY KEY  (`group_id`),
  KEY `site_id` (`site_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

--
-- Table structure for table `user_group_product`
--

CREATE TABLE IF NOT EXISTS `user_group_product` (
  `user_group_product_id` bigint(20) unsigned NOT NULL auto_increment,
  `group_id` mediumint(9) NOT NULL default '0',
  `product_id` mediumint(9) NOT NULL default '0',
  `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`user_group_product_id`),
  KEY `product_id` (`product_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=124 ;

--
-- Table structure for table `product`
--

CREATE TABLE IF NOT EXISTS `product` (
  `product_id` mediumint(8) unsigned NOT NULL auto_increment,
  `payment_enabled` tinyint(1) NOT NULL default '0',
  `credit_enabled` tinyint(1) NOT NULL default '0',
  `product_name` varchar(100) NOT NULL default 'Default Product',
  `is_public` tinyint(1) NOT NULL default '1',
  `product_price` decimal(10,2) default NULL,
  `product_currency` varchar(5) default NULL,
  PRIMARY KEY  (`product_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

1 个答案:

答案 0 :(得分:1)

如果我已正确理解您的要求,这应该有效:

SELECT u.id as user_id, u.username, ug.group_id, ug.group_name, u.firstname, u.surname, p.product_name, p.product_id, p.product_price, p.product_currency, p.is_public
FROM user_groups ug
JOIN user_group_users ugu ON ug.group_id = ugu.group_id
JOIN users u ON u.id  = ugu.user_id
JOIN user_group_product ugp on ug.group_id = ugp.group_id
JOIN product p on p.product_id = ugp.product_id
WHERE u.site_id = 5
UNION ALL
SELECT u.id user_id, u.username, NULL group_id, NULL group_name, u.firstname, u.surname, p.product_name, p.product_id, p.product_price, p.product_currency, p.is_public
FROM users
CROSS JOIN product p
WHERE p.is_public = 1
ORDER BY 4 desc, 6, 5, 2

- 它应该返回站点5上的用户具有组访问权限的所有产品,以及所有用户的所有公共产品。