我有一个用户表(user_id
,name
,...)和一个表(group_id
,description
,...)。 description
包含一个字符串,其中包含该特定组中的所有用户(user1
,user2
...)。有些用户不属于任何组。
我希望获得群组中的所有用户。我已经尝试了LIKE
语句,但它没有用。它看起来像这样:
Select users.name
FROM users, groups
WHERE users.name LIKE '%' + groups.description + '%'
当我插入一个特定用户名(... LIKE '%'"user1"'%'
)
答案 0 :(得分:1)
由于缺乏样本数据和结果,您的问题非常明显。但如果groups.description
包含一个或多个用户名,那么您的LIKE
操作数就是错误的方法。要检查用户名是否在群组的用户字符串列表中,您需要groups.description like '%' + users.name + '%'
然后你应该开始使用正确的SQL连接,而不是容易出错的1992年之前的语法,这样就可以了:
select
users.name,
groups.group_id
from users
inner join groups on groups.description like '%' + users.name + '%';
这将返回用户及其所属群组的列表...如果您很幸运。因为这是一个非常脆弱的设计。这是一个思想实验:如果某些用户的名称是其他用户的子串,该怎么办?名称,但这些用户不属于同一组?
无论哪种方式,您都应该使用一个单独的表来将用户映射到组,以实现正确的规范化以及更容易/更易于维护的查询。
答案 1 :(得分:1)
以下表值函数可能在这里使用:
CREATE FUNCTION [dbo].[fnSplitStrings]
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
AS
RETURN (SELECT Number = ROW_NUMBER() OVER (ORDER BY Number),
Item FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@List, Number,
CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)))
FROM (SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1 CROSS APPLY sys.all_objects) AS n(Number)
WHERE Number <= CONVERT(INT, LEN(@List))
AND SUBSTRING(@Delimiter + @List, Number, 1) = @Delimiter
) AS y);
此函数将拆分某个列并为每个值返回一个新行。
以下是如何使用它的示例:
SELECT
g.group_id,
f.item
FROM groups g
CROSS APPLY dbo.fnSplitStrings(g.Description, ', ') AS f
--You could even join the actual users if necessary
SELECT
g.group_id,
f.item,
u.user_id
FROM groups g
CROSS APPLY dbo.fnSplitStrings(g.Description, ', ') AS f
INNER JOIN users u ON u.name = f.item
如果还有其他不清楚的地方,请发表评论。
答案 2 :(得分:1)
您有2个表,'用户'和'组',您创建第三个表'UsersInGroups',其中包含2个字段:'id_user'和'id_group'。做出选择:
select u.name from Users u
join UsersInGroups gu on u.user_id = gu.user_id
join Groups g on gu.group_id = g.group_id
where g.name = 'GroupName' --or g.group_id = YourId