我有3张桌子:
最初所有用户都没有功能
示例数据:
用户:
| id | name |
| 1 | Rex |
| 2 | Job |
特点:
| id | name |
| 1 | Eat |
| 2 | Walk |
User_has_Feature:
| id | user_id | feature_id | have_feature |
| 1 | 1 | 1 | true |
| 2 | 1 | 1 | true |
| 3 | 2 | 2 | true |
| 4 | 2 | 2 | false |
示例:
| user_name | feature_name | feature_status |
| Rex | Eat | true |
| Rex | Walk | true |
示例:
| user_name | feature_name | feature_status |
| Job | Eat | true |
| Job | Walk | false |
我们的想法是将结果导出为CSV文件
感谢(@RolandoMySQLDBA,@ Tom Ingram,@ DRapp)的答案,我找到了一个解决方案:
SELECT u.name, f.name, IF(uhf.status=1,'YES','NO') as status
FROM user u
JOIN user_has_feature uhf ON u.id = uhf.user_id
JOIN feature f ON f.id = uhf.feature_id
JOIN
(
SELECT u.id as id
FROM user u
JOIN user_has_feature uhf ON uhf.user_id = u.id
WHERE uhf.status = 1
GROUP BY u.id
HAVING count(u.id) <= (SELECT COUNT(1) FROM feature)
) as `condition` ON `condition`.id = u.id
ORDER BY u.name, f.id, uhf.status
对于获取没有所有功能的记录,并获取所有功能都发生变化的记录:
WHERE uhf.status = 1
WHERE uhf.status = 2
HAVING count(u.id) <= (SELECT COUNT(1) FROM feature)
HAVING count(u.id) = (SELECT COUNT(1) FROM feature)
但我想知道这是否是最佳解决方案?
答案 0 :(得分:1)
SELECT
UNF.*,
IF(
(LENGTH(UNF.FeatureList) - LENGTH(REPLACE(UNF.FeatureList,',','')))
= (FC.FeatureCount - 1),'Has All Features','Does Not Have All Features'
) HasAllFeatures
FROM
(SELECT
U.name user_name
GROUP_CONCAT(F.name) Features
FROM
(SELECT user_id,feature_id FROM User_has_Feature
WHERE feature_status = true) UHF
INNER JOIN User U ON UHF.user_id = U.id
INNER JOIN Feature F ON UHF.feature_id = F.id
GROUP BY
U.name
) UNF,
(SELECT COUNT(1) FeatureCount FROM Feature) FC
;
UNF子查询返回User_has_Feature中列出的所有用户以及以逗号分隔的功能列表。列HasAllFeatures
由UNF.FeatureList
中的列数决定。在您的情况下,有两个功能。如果UNF.FeatureList中的逗号数是FeatureCount - 1,则该用户具有所有功能。否则,用户没有所有功能。
这是一个更好的版本,显示所有用户以及他们是否具有全部,部分或无功能
SELECT
U.name user_name,
IFNULL(UsersAndFeatures.HasAllFeatures,
'Does Not Have Any Features')
WhatFeaturesDoesThisUserHave
FROM
User U LEFT JOIN
(
SELECT
UHF.user_id id,
IF(
(LENGTH(UHF.FeatureList) - LENGTH(REPLACE(UHF.FeatureList,',','')))
= (FC.FeatureCount - 1),
'Has All Features',
'Does Not Have All Features'
) HasAllFeatures
FROM
(
SELECT user_id,GROUP_CONCAT(Feature.name) FeatureList
FROM User_has_Feature INNER JOIN Feature
ON User_has_Feature.feature_id = Feature.id
GROUP BY user_id
) UHF,
(SELECT COUNT(1) FeatureCount FROM Feature) FC
) UsersAndFeatures
USING (id);
答案 1 :(得分:1)
select
u.id,
u.name as User_Name,
f.name as Feature_Name,
uhf.feature_Status
from
( select uhf.user_id,
sum( if( uhf.feature_status, 1, 0 ) ) as UserFeatureCount
from user_has_feature uhf
group by uhf.user_id ) AllUsersWithCounts
join
( select count(*) as AllFeaturesCount
from Feature ) AllFeatures
on AllUsersWithCounts.UserFeatureCount = AllFeatures.AllFeaturesCount
join user u
on AllUsersWithCounts.user_id = u.ID
join user_has_feature uhf
on AllUsersWithCounts.User_id = uhf.user_id
join feature f
on uhf.feature_id = f.id
以上查询应该让所有明确拥有所有功能的人都可以。为了获得那些没有所有功能的人,只需将一个连接从=更改为&lt;
on AllUsersWithCounts.UserFeatureCount < AllFeatures.AllFeaturesCount
答案 2 :(得分:0)
这是我的bash
创建一般信息的视图
CREATE VIEW v_users_have_features AS
SELECT usr.id, usr.name, feature.name, has_feature.status
FROM usr
JOIN has_feature ON usr.id = has_feature.user_id
JOIN feature ON has_feature.feature_id = feature.id;
将视图用于其他查询
SELECT v_users_have_features.id, v_users_have_features.u_name, v_users_have_features.f_name
FROM v_users_have_features
GROUP BY v_users_have_features.id
HAVING COUNT( v_users_have_features.id ) = (SELECT COUNT( feature.id )
FROM feature
WHERE feature.name = v_users_have_features.f_name )
P.S。您可能需要适应(特别是后者)您的确切要求,您也可以省略创建视图并将其嵌套在FROM
子句中,就像在另一个答案中一样,创建视图似乎更方便
答案 3 :(得分:-1)
计算要素数量。在使用相关子查询的用户上编写查询,以查找用户拥有的所有功能并对其进行计数。在顶部查询中设置限制条件,使该计数与全局特征数相等。
MySQL能否进行相关子查询?如果没有,您可能需要使用更好的数据库。