【发布时间】:2018-04-13 00:59:25
【问题描述】:
我的 Web 应用程序需要所有用户组、组成员的列表,以及他们根据组成员身份有权访问的产品列表。
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 ;
【问题讨论】:
-
您是否尝试过
INNER JOIN而不是LEFT和RIGHT加入并将此条件添加到WHERE子句? -
你能包括你的表结构吗?您的问题是,“网站是这些用户、组和产品的唯一标识符”;您当前是按站点选择用户,而不是组或产品。
-
@Mahmoud Gamal - 感谢您的建议,但是我没有明确说明我必须返回该站点的所有用户,即使他们没有组访问权限,因为这些用户可以访问公共产品,即is_public=1。我现在已将此添加到原始问题中。
-
users 和 user_groups 上都有
site_id- 这些应该总是相同的吗?如果没有,您是否要包括无法通过自己的users记录访问站点 5,但可以通过其user_groups记录访问的用户? -
@MarkBannister - 感谢您的 cmets。 site_id 值在两个表中重复且相同。因此,我需要用户有权访问(通过组成员身份)或产品是公开的所有用户、所有组和所有产品。