我有一个以下结构的表。
select loginid,alloted_area from tbllogin
返回此结果。
loginid alloted_area
------------- ---------------------------
01900017 22,153,169,174,179,301
01900117 254,91,92,285,286,287
01900217 2,690,326,327,336
17900501 null
17900601 28,513,409,410
17901101 254,91,92,285
17901701 59,1302,1303
17902101 2,690,326,327
17902301 20,159,371,161
17902401 null
我有另一个表
tblarea
,当一个区域分配给用户时,其 id 存储在上述表中的逗号分隔值中。我想加入这两个表并留下像最后一个尚未分配区域的条目。现在我已经多次被告知以逗号分隔值存储数据是一种不好的做法(我想这是因为我面临的问题)我知道但是这个结构是由我公司的另一个开发人员创建的,而不是我请帮忙而不是投反对票。这是我尝试过的:declare @csv varchar(max)='';
SELECT @CSV = COALESCE(@CSV + ', ', '') + case when alloted_area is null or alloted_area='' then '0' else alloted_area end from tbllogin;
select * from tblarea where id in (select 0 union select sID from splitstring(@CSV,','));
这确实获得了该区域,但它无法为我提供该区域已分配给的用户的登录信息。样本输入和输出。
登录
loginid alloted_area
------------- ---------------------------
a1 1,3,5
a2 2,4
a3 1,4
a4 null
区域
id area_name
------------- ---------------------------
1 v
2 w
3 x
4 y
5 z
加入后我需要这个结果
login_id area_name
------------- ---------------------------
a1 v
a1 x
a1 z
a2 w
a2 y
a3 v
a3 y
最佳答案
通过使用拆分和交叉应用,我们可以实现所需的输出
DECLARE @tbllogin TABLE (LoginID CHAR(2) NOT NULL PRIMARY KEY, alloted_area VARCHAR(MAX));
INSERT @tblLogin (LoginID, alloted_area)
VALUES ('a1', '1,3,5'), ('a2', '2,4'),('a3', '1,4'), ('a4', NULL);
DECLARE @tblArea TABLE (ID INT NOT NULL PRIMARY KEY, Area_Name CHAR(1));
INSERT @tblArea (ID, Area_Name)
VALUES (1, 'v'), (2, 'w'), (3, 'x'), (4, 'y'), (5, 'z');
SELECT Dt.LoginID,A.Area_Name FROm
(
SELECT LoginID,Split.a.value('.', 'VARCHAR(1000)') AS alloted_area
FROM (
SELECT LoginID,CAST('<S>' + REPLACE(alloted_area, ',', '</S><S>') + '</S>' AS XML) AS alloted_area
FROM @tbllogin
) AS A
CROSS APPLY alloted_area.nodes('/S') AS Split(a)
)DT
Inner join
@tblArea A
on A.ID=DT.alloted_area
输出
LoginID Area_Name
--------------------
a1 v
a1 x
a1 z
a2 w
a2 y
a3 v
a3 y
关于sql - 由于逗号分隔值,无法弄清楚如何连接表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44582176/