首先,我要告訴你你應該怎麼做......規範你的表。
如果有問題的表是用戶角色表,那麼將您的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