亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > SQL Server > 正文

一列保存多個ID(將多個用逗號隔開的ID轉換成用逗號隔開的名稱)

2024-08-31 00:57:13
字體:
來源:轉載
供稿:網友
背景:在做項目時,經常會遇到這樣的表結構在主表的中有一列保存的是用逗號隔開ID。如,當一個員工從屬多個部門時、當一個項目從屬多個城市時、當一個設備從屬多個項目時,很多人都會在員工表中加入一個deptIds VARCHAR(1000)列(本文以員工從屬多個部門為例),用以保存部門編號列表(很明顯這不符合第一范式,但很多人這樣設計了,在這篇文章中我們暫不討論在這種應用場景下,如此設計的對與錯,有興趣的可以在回復中聊聊),然后我們在查詢列表中需要看到這個員工從屬哪些部門。
初始化數據:
部門表、員工表數據:

復制代碼 代碼如下:



IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Department]'))
DROP TABLE [dbo].Department
GO
--部門表
CREATE TABLE Department
(
id int,
name nvarchar(50)
)
INSERT INTO Department(id,name)
SELECT 1,'人事部'
UNION
SELECT 2,'工程部'
UNION
SELECT 3,'管理部'
SELECT * FROM Department

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Employee]'))
DROP TABLE [dbo].Employee
GO
--員工表
CREATE TABLE Employee
(
id int,
name nvarchar(20),
deptIds varchar(1000)
)
INSERT INTO Employee(id,name,deptIds)
SELECT 1,'蔣大華','1,2,3'
UNION
SELECT 2,'小明','1'
UNION
SELECT 3,'小華',''
SELECT * FROM Employee


一列保存多個ID(將多個用逗號隔開的ID轉換成用逗號隔開的名稱)

希望得到的結果:

解決方法:

第一步,是得到如下的數據。即將員工表集合與相關的部門集合做交叉連接,其中使用了fun_SplitIds函數(作用是將ids分割成id列表),然后員工集合與這個得到的集合做交叉連接

復制代碼 代碼如下:


SELECT E.*,ISNULL(D.name,'') AS deptName
FROM Employee AS E
OUTER APPLY dbo.fun_SplitIds(E.deptIds) AS DID
LEFT JOIN Department AS D ON DID.ID=D.id;


一列保存多個ID(將多個用逗號隔開的ID轉換成用逗號隔開的名稱)

第二步,已經得到了如上的數據,然后要做的就是根據ID分組,并對deptName列做聚合操作,但可惜的是SQL SERVER還沒有提供對字符串做聚合的操作。但想到,我們處理樹形結構數據時,用CTE來做關系數據,做成有樹形格式的數據,如此我們也可以將這個問題轉換成做樹形格式的問題,代碼如下:

復制代碼 代碼如下:


;WITH EmployeT AS(
--員工的基本信息(使用OUTER APPLY將多個ID拆分開來,然后與部門表相關聯)
--此時已將員工表所存的IDS分別與部門相關聯,下面需要將此集合中的deptName聚合成一個記錄
SELECT E.*,ISNULL(D.name,'') AS deptName
FROM Employee AS E
OUTER APPLY dbo.fun_SplitIds(E.deptIds) AS DID
LEFT JOIN Department AS D ON DID.ID=D.id
),mike AS(
SELECT id,name,deptIds,deptName
,ROW_NUMBER()OVER(PARTITION BY id ORDER BY id) AS level_num
FROM EmployeT
),mike2 AS(
SELECT id,name,deptIds,CAST(deptName AS NVARCHAR(100)) AS deptName,level_num
FROM mike
WHERE level_num=1
UNION ALL
SELECT m.id,m.name,m.deptIds,CAST(m2.deptName+','+m.deptName AS NVARCHAR(100)) AS deptName,m.level_num
FROM mike AS m
INNER JOIN mike2 AS m2 ON m.ID=m2.id AND m.level_num=m2.level_num+1
),maxMikeByIDT AS(
SELECT id,MAX(level_num) AS level_num
FROM mike2
GROUP BY ID
)

SELECT A.id,A.name,A.deptIds,A.deptName
FROM mike2 AS A
INNER JOIN maxMikeByIDT AS B ON A.id=B.ID AND A.level_num=B.level_num
ORDER BY A.id OPTION (MAXRECURSION 0)


結果如下:

全部SQL:

復制代碼 代碼如下:


IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Department]'))
DROP TABLE [dbo].Department
GO
--部門表
CREATE TABLE Department
(
id int,
name nvarchar(50)
)
INSERT INTO Department(id,name)
SELECT 1,'人事部'
UNION
SELECT 2,'工程部'
UNION
SELECT 3,'管理部'

SELECT * FROM Department


IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Employee]'))
DROP TABLE [dbo].Employee
GO
--員工表
CREATE TABLE Employee
(
id int,
name nvarchar(20),
deptIds varchar(1000)
)
INSERT INTO Employee(id,name,deptIds)
SELECT 1,'蔣大華','1,2,3'
UNION
SELECT 2,'小明','1'
UNION
SELECT 3,'小華',''

SELECT * FROM Employee

--創建一個表值函數,用來拆分用逗號分割的數字串,返回只有一列數字的表
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fun_SplitIds]'))
DROP FUNCTION [dbo].fun_SplitIds
GO
CREATE FUNCTION dbo.fun_SplitIds(
@Ids nvarchar(1000)
)
RETURNS @t_id TABLE (id VARCHAR(36))
AS
BEGIN
DECLARE @i INT,@j INT,@l INT,@v VARCHAR(36);
SET @i = 0;
SET @j = 0;
SET @l = len(@Ids);
while(@j < @l)
begin
SET @j = charindex(',',@Ids,@i+1);
IF(@j = 0) set @j = @l+1;
SET @v = cast(SUBSTRING(@Ids,@i+1,@j-@i-1) as VARCHAR(36));
INSERT INTO @t_id VALUES(@v)
SET @i = @j;
END
RETURN;
END
GO


;WITH EmployeT AS(
--員工的基本信息(使用OUTER APPLY將多個ID拆分開來,然后與部門表相關聯)
--此時已將員工表所存的IDS分別與部門相關聯,下面需要將此集合中的deptName聚合成一個記錄
SELECT E.*,ISNULL(D.name,'') AS deptName
FROM Employee AS E
OUTER APPLY dbo.fun_SplitIds(E.deptIds) AS DID
LEFT JOIN Department AS D ON DID.ID=D.id
),mike AS(
SELECT id,name,deptIds,deptName
,ROW_NUMBER()OVER(PARTITION BY id ORDER BY id) AS level_num
FROM EmployeT
),mike2 AS(
SELECT id,name,deptIds,CAST(deptName AS NVARCHAR(100)) AS deptName,level_num
FROM mike
WHERE level_num=1
UNION ALL
SELECT m.id,m.name,m.deptIds,CAST(m2.deptName+','+m.deptName AS NVARCHAR(100)) AS deptName,m.level_num
FROM mike AS m
INNER JOIN mike2 AS m2 ON m.ID=m2.id AND m.level_num=m2.level_num+1
),maxMikeByIDT AS(
SELECT id,MAX(level_num) AS level_num
FROM mike2
GROUP BY ID
)

SELECT A.id,A.name,A.deptIds,A.deptName
FROM mike2 AS A
INNER JOIN maxMikeByIDT AS B ON A.id=B.ID AND A.level_num=B.level_num
ORDER BY A.id OPTION (MAXRECURSION 0)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产国语刺激对白av不卡| 中文字幕久热精品在线视频| 国产网站欧美日韩免费精品在线观看| 日韩av不卡电影| 国产91精品最新在线播放| 欧美激情亚洲国产| 97免费在线视频| 精品综合久久久久久97| 欧美成年人网站| 成人97在线观看视频| 久久久www成人免费精品张筱雨| 欧洲精品毛片网站| 成人在线视频福利| 欧美性做爰毛片| 日本精品久久中文字幕佐佐木| 亚洲自拍偷拍一区| 久久成人这里只有精品| 国产免费观看久久黄| 日韩专区在线播放| 在线日韩日本国产亚洲| 欧洲成人免费aa| 久久久久久久久综合| 亚洲成人在线网| 91在线高清免费观看| 久久亚洲精品国产亚洲老地址| 亚洲人成电影网站| 久久影院免费观看| 亚洲人a成www在线影院| 欧美在线播放视频| 国产精品色午夜在线观看| 欧美中文在线免费| 国产三级精品网站| 亚洲少妇激情视频| 日韩在线一区二区三区免费视频| 91探花福利精品国产自产在线| 亚洲激情电影中文字幕| 91福利视频网| 亚洲人在线视频| 一区二区三区动漫| 97欧美精品一区二区三区| 亚洲欧美日韩中文视频| 一区二区三区国产视频| 中文字幕av日韩| 欧美精品在线观看91| 最新的欧美黄色| 中文字幕日韩欧美在线| 国产日韩在线看片| 国产成人亚洲综合91| 日韩精品黄色网| 欧美肥婆姓交大片| 精品久久香蕉国产线看观看gif| 久久久国产一区| 青青a在线精品免费观看| 国产97在线亚洲| 91日韩在线视频| 亚洲理论在线a中文字幕| 亚洲精品成人免费| 欧美日韩综合视频网址| 亚洲免费视频在线观看| 亚洲国产精品va在线看黑人| 亚洲精品国产品国语在线| 日韩视频永久免费观看| 亚洲第一男人天堂| 欧美国产日韩中文字幕在线| 亚洲天堂视频在线观看| 亚洲一区二区三区四区在线播放| 欧美黄色性视频| 久久久av网站| 欧美极品欧美精品欧美视频| 最近中文字幕mv在线一区二区三区四区| 国产在线视频不卡| 成人性生交大片免费看小说| 久久人人爽人人爽人人片亚洲| 91精品中国老女人| 日韩美女免费线视频| 国产精品久久久久91| 国产精品嫩草影院一区二区| 久久99视频免费| 毛片精品免费在线观看| 国产精品美女久久久久av超清| 国产精品视频资源| 亚洲精品www久久久| 精品福利在线视频| 亚洲肉体裸体xxxx137| 日韩亚洲欧美中文在线| 91精品国产91久久久| 亚洲最大成人免费视频| 91精品久久久久久久久青青| 亚洲欧美激情精品一区二区| 亚洲日本成人女熟在线观看| 亚洲成人网在线| 7777精品久久久久久| 久久成人综合视频| 成人97在线观看视频| 欧美成人sm免费视频| 国产精品亚洲激情| 欧美日韩免费区域视频在线观看| 欧美寡妇偷汉性猛交| 午夜精品久久久久久久99热浪潮| 亚洲第一区中文字幕| 久久理论片午夜琪琪电影网| 色先锋久久影院av| 亚洲欧美精品一区二区| 黑人精品xxx一区一二区| 日韩性xxxx爱| 日韩精品亚洲元码| 久久视频免费在线播放| 色黄久久久久久| 欧美高清videos高潮hd| 久久精品国产视频| 中文字幕久久久| 中文字幕在线看视频国产欧美| 国产精品高清在线观看| 国产狼人综合免费视频| 精品少妇一区二区30p| 国产精品国产三级国产aⅴ浪潮| 中文字幕亚洲欧美日韩在线不卡| 欧美激情综合亚洲一二区| 91热精品视频| 亚洲精品久久在线| 91在线观看免费| 亚洲精品成人免费| 亚洲色图17p| 18一19gay欧美视频网站| 欧美日韩免费网站| www.亚洲成人| 欧美日韩电影在线观看| 国产精品成人观看视频国产奇米| 日韩动漫免费观看电视剧高清| 日韩av影片在线观看| 亚洲第一网中文字幕| 日韩成人免费视频| 成人在线小视频| 亚洲欧美制服中文字幕| 成人免费自拍视频| 在线视频免费一区二区| 国产精品日韩欧美大师| 国产精品久久久久aaaa九色| 亚洲www视频| 国产做受高潮69| 中文字幕日韩免费视频| 精品爽片免费看久久| 国产精品视频午夜| 国产69精品久久久久9999| 国产精品久久久久久久久久免费| 亚洲xxxx3d| 精品国产电影一区| 欧美在线免费观看| 精品久久久久久久久久| 在线性视频日韩欧美| 久久久国产精彩视频美女艺术照福利| 日韩欧美一区二区三区| 在线视频欧美日韩| 欧美日韩国产二区| 欧美激情亚洲自拍| 影音先锋欧美精品| 久久久久久久久久久网站| 国产剧情久久久久久| 成人黄色av网| 亚洲视频欧美视频| 清纯唯美亚洲综合| 中文字幕日韩欧美精品在线观看| 中文字幕九色91在线| 国产精国产精品|