首先,我要告诉你你应该怎么做......规范你的表。
如果有问题的表是用户角色表,那么将您的user_role列拆分为单个值。如果它是包含其他列的较大表的一部分,则应使用单独的表来存储用户角色信息。我还建议为每个值分配不同的级别,因此您不必分析字符串。
例如,有一个像
CREATE TABLE userRoles (userID INT, userRole INT);
一个user_roles表...然后有一个角色表所示:
CREATE TABLE Roles (userRole INT IDENTITY(1, 1), roleDescription VARCHAR(255), roleLevel INT);
INSERT Roles (roleDescription, roleLevel) VALUES ('guest', 1), ('user_guest', 2), ('user_Admin', 3);
......这样一来,你可以找到做管理员角色加入并寻找3级而不是解析字符串。如果你的表很小,没有什么大不了的,但是你的表越大,解析字符串的成本就越高。通过适当的索引,这将成为检索所需数据的最快方法,同时还可以根据需要轻松更改数据(需要更改角色名称?没问题...在Roles表中编辑roleDescription)。
但是做不到这一点,这里有一对夫妇的解决方案,你可以考虑......
declare @1 table (ID INT IDENTITY(1, 1), User_Role varchar(255));
insert @1 (User_Role) values ('guest|hello_Kitty_Admin|user_guest'),('user_Admin_zzz|guest'),('guest|user_guest|greatest_admin_of_all_time'),('user_guest|user_Admin2'),('user_Admin'),('regular_user');
with t as (
select id, user_role, left(User_Role, charindex('admin', User_Role) + isnull(nullif(charindex('|', substring(User_Role, charindex('admin', User_Role), len(User_Role))), 0) - 2, len(User_Role))) zzz
from @1)
select id, isnull(right(zzz, isnull(nullif(charindex('|', reverse(zzz)), 0) - 1, len(zzz))), user_role) adminrole
from t;
...上述所有正在做的是解析您USER_ROLE柱,发现其中admin是和获取一切行括号之间该值(如果不存在,它只是返回全额USER_ROLE)
declare @2 table(ID INT IDENTITY(1, 1), User_Role varchar(255));
insert @2 (User_Role) values ('guest|hello_Kitty_Admin|user_guest'),('user_Admin_zzz|guest'),('guest|user_guest|greatest_admin_of_all_time'),('user_guest|user_Admin2'),('user_Admin'),('regular_user');
with cte as (
select id, user_role, substring(user_role, 1, isnull(nullif(charindex('|', user_role), 0) - 1, len(user_role))) roles, nullif(charindex('|', user_role), 0) cindex, 1 L
from @2
union all
select id, user_role, substring(user_role, cindex+1, isnull(nullif(charindex('|', user_role, cindex+1), 0) - 1 - cindex, len(user_role))), nullif(charindex('|', user_role, cindex+1), 0), L + 1
from cte
where cindex is not null)
select id, max(isnull(x.y, user_role)) adminrole
from cte t
outer apply (
select min(roles) over (partition by len(roles))
from cte
where id = t.id
and roles like '%admin%') x(y)
group by id, x.y
order by id;
...这是在做同样的事情,另外一个用不同的方法。
或者您可以使用类似于其他答案的光标,稍作修改。
但真的,正常化!
你可以写一个case语句,例如'CASE WHEN User_Role LIKE'%user_Admin%'THEN'user_Admin'END'或者如果你只想要user_Admin作为用户角色的用户,那么'SELECT'user_Admin'FROM myTable WHERE User_Role LIKE'%user_Admin%''或类似的东西。 – ZLK
[在sql中管道分隔的列中搜索值的可能重复](http://stackoverflow.com/questions/18767077/search-value-in-column-which-is-pipe-separated-in-sql) –
我不想硬编码价值。我想从数据中推导出它。 – turbo88