从带数字的数组字符串到数组字符串文本的查询结果?
Query result from array string with numbers to array string text?
我有两个 SQL 服务器 table。
第一个table:Product
Id
Title
Tags
1
P1583
2,5
2
P1234
1,3
3
P1456
1
第二个 table - Tag
:
Id
Title
1
Pants
2
Shorts
3
Shirts
4
Tshirts
5
Skirts
我想要这个结果
ProductId
Title
TagName
1
P1583
Short,Skirts
2
P1234
Pants,Shirts
3
P1456
Pants
如何编写查询?
SELECT
P.Id AS ProductId,
P.Title AS Title,
????
FROM
Product P
LEFT JOIN
Tag T ON T.Id = P.Tags --- (this is not working)
你的table
declare @r TABLE (
Id int NOT NULL
,Title VARCHAR(10) NOT NULL
,Tags VARCHAR(30) NOT NULL
);
INSERT INTO @r(Id,Title,Tags) VALUES (1,'P1583','2,5');
INSERT INTO @r(Id,Title,Tags) VALUES (2,'P1234','1,3');
INSERT INTO @r(Id,Title,Tags) VALUES (3,'P1456','1');
declare @t TABLE (
Id int NOT NULL PRIMARY KEY
,Title VARCHAR(70) NOT NULL
);
INSERT INTO @t(Id,Title) VALUES (1,'Pants');
INSERT INTO @t(Id,Title) VALUES (2,'Shorts');
INSERT INTO @t(Id,Title) VALUES (3,'Shirts');
INSERT INTO @t(Id,Title) VALUES (4,'Tshirts');
INSERT INTO @t(Id,Title) VALUES (5,'Skirts');
生成结果的查询应该拆分标签并再次与第二个 table
的标题合并
with t as(
SELECT Id,Title,
PARSENAME(REPLACE(Tags,',','.'),2) 'Tag1' ,
PARSENAME(REPLACE(Tags,',','.'),1) 'Tag2'
FROM @r)
select t.id,t.Title,concat(t1.Title,iif(t1.Title is null,'',','),t2.Title)
tagName from t
full join @t t1 on t1.id=t.Tag1
join @t t2 on t2.id=t.Tag2
因此,创建数据:
CREATE TABLE #t (id int, title nvarchar(5), tags nvarchar(3));
INSERT INTO #t (id,title,tags)
VALUES
(1,'P1583','2,5'),
(2,'P1234','1,3'),
(3,'P1456','1');
CREATE TABLE #tag (id int, title nvarchar(10));
INSERT INTO #tag (id,title)
VALUES
(1,'Pants'),
(2,'Shorts'),
(3,'Shirts'),
(4,'Tshirts'),
(5,'Skirts');
并且使用 STRING_SPLIT 和 CROSS APPLY 给我们:
SELECT #t.id, #t.title, #t.tags, tags.value, #tag.title
FROM #t
CROSS APPLY STRING_SPLIT(#t.tags,',') tags
INNER JOIN #tag ON tags.value = #tag.id;
id
title
tags
value
title
1
P1583
2,5
2
Shorts
1
P1583
2,5
5
Skirts
2
P1234
1,3
1
Pants
2
P1234
1,3
3
Shirts
3
P1456
1
1
Pants
从那里你们 STRING_AGG 回到了一起:
WITH exp
AS (
SELECT #t.id, #t.title, #t.tags, tags.value, #tag.title AS tag_title
FROM #t
CROSS APPLY STRING_SPLIT(#t.tags,',') tags
INNER JOIN #tag ON tags.value = #tag.id
)
SELECT id, title, STRING_AGG(tag_title,',') WITHIN GROUP (ORDER BY tag_title) AS tag_titles
FROM exp
GROUP BY id, title;
进行拆分和 re-aggregate 的另一种方法是修改@FlexYourData 的出色答案:
SELECT
p.Id,
p.Title,
tags.TagName
FROM Product p
CROSS APPLY (
SELECT
TagName = STRING_AGG(t.Title, ',')
FROM STRING_SPLIT(p.Tags, ',') tags
INNER JOIN Tag t ON tags.value = t.id
) tags;
理想情况下,您应该规范化架构并创建单独的联接 table:
CREATE TABLE ProductTag (
ProductId REFERENCES Product (Id),
TagId REFERENCES Tag (Id)
);
INSERT ProductTag (ProductId, TagId)
SELECT
p.Id,
tags.value
FROM Product p
CROSS APPLY STRING_SPLIT(p.Tags, ',') tags;
那么您的查询变为:
SELECT
p.Id,
p.Title,
tags.TagName
FROM Product p
CROSS APPLY (
SELECT
TagName = STRING_AGG(t.Title, ',')
FROM ProductTags pt
INNER JOIN Tag t ON pt.TagId = t.id
WHERE pt.ProductId = p.Id
) tags;
我有两个 SQL 服务器 table。
第一个table:Product
Id | Title | Tags |
---|---|---|
1 | P1583 | 2,5 |
2 | P1234 | 1,3 |
3 | P1456 | 1 |
第二个 table - Tag
:
Id | Title |
---|---|
1 | Pants |
2 | Shorts |
3 | Shirts |
4 | Tshirts |
5 | Skirts |
我想要这个结果
ProductId | Title | TagName |
---|---|---|
1 | P1583 | Short,Skirts |
2 | P1234 | Pants,Shirts |
3 | P1456 | Pants |
如何编写查询?
SELECT
P.Id AS ProductId,
P.Title AS Title,
????
FROM
Product P
LEFT JOIN
Tag T ON T.Id = P.Tags --- (this is not working)
你的table
declare @r TABLE (
Id int NOT NULL
,Title VARCHAR(10) NOT NULL
,Tags VARCHAR(30) NOT NULL
);
INSERT INTO @r(Id,Title,Tags) VALUES (1,'P1583','2,5');
INSERT INTO @r(Id,Title,Tags) VALUES (2,'P1234','1,3');
INSERT INTO @r(Id,Title,Tags) VALUES (3,'P1456','1');
declare @t TABLE (
Id int NOT NULL PRIMARY KEY
,Title VARCHAR(70) NOT NULL
);
INSERT INTO @t(Id,Title) VALUES (1,'Pants');
INSERT INTO @t(Id,Title) VALUES (2,'Shorts');
INSERT INTO @t(Id,Title) VALUES (3,'Shirts');
INSERT INTO @t(Id,Title) VALUES (4,'Tshirts');
INSERT INTO @t(Id,Title) VALUES (5,'Skirts');
生成结果的查询应该拆分标签并再次与第二个 table
的标题合并with t as(
SELECT Id,Title,
PARSENAME(REPLACE(Tags,',','.'),2) 'Tag1' ,
PARSENAME(REPLACE(Tags,',','.'),1) 'Tag2'
FROM @r)
select t.id,t.Title,concat(t1.Title,iif(t1.Title is null,'',','),t2.Title)
tagName from t
full join @t t1 on t1.id=t.Tag1
join @t t2 on t2.id=t.Tag2
因此,创建数据:
CREATE TABLE #t (id int, title nvarchar(5), tags nvarchar(3));
INSERT INTO #t (id,title,tags)
VALUES
(1,'P1583','2,5'),
(2,'P1234','1,3'),
(3,'P1456','1');
CREATE TABLE #tag (id int, title nvarchar(10));
INSERT INTO #tag (id,title)
VALUES
(1,'Pants'),
(2,'Shorts'),
(3,'Shirts'),
(4,'Tshirts'),
(5,'Skirts');
并且使用 STRING_SPLIT 和 CROSS APPLY 给我们:
SELECT #t.id, #t.title, #t.tags, tags.value, #tag.title
FROM #t
CROSS APPLY STRING_SPLIT(#t.tags,',') tags
INNER JOIN #tag ON tags.value = #tag.id;
id | title | tags | value | title |
---|---|---|---|---|
1 | P1583 | 2,5 | 2 | Shorts |
1 | P1583 | 2,5 | 5 | Skirts |
2 | P1234 | 1,3 | 1 | Pants |
2 | P1234 | 1,3 | 3 | Shirts |
3 | P1456 | 1 | 1 | Pants |
从那里你们 STRING_AGG 回到了一起:
WITH exp
AS (
SELECT #t.id, #t.title, #t.tags, tags.value, #tag.title AS tag_title
FROM #t
CROSS APPLY STRING_SPLIT(#t.tags,',') tags
INNER JOIN #tag ON tags.value = #tag.id
)
SELECT id, title, STRING_AGG(tag_title,',') WITHIN GROUP (ORDER BY tag_title) AS tag_titles
FROM exp
GROUP BY id, title;
进行拆分和 re-aggregate 的另一种方法是修改@FlexYourData 的出色答案:
SELECT
p.Id,
p.Title,
tags.TagName
FROM Product p
CROSS APPLY (
SELECT
TagName = STRING_AGG(t.Title, ',')
FROM STRING_SPLIT(p.Tags, ',') tags
INNER JOIN Tag t ON tags.value = t.id
) tags;
理想情况下,您应该规范化架构并创建单独的联接 table:
CREATE TABLE ProductTag (
ProductId REFERENCES Product (Id),
TagId REFERENCES Tag (Id)
);
INSERT ProductTag (ProductId, TagId)
SELECT
p.Id,
tags.value
FROM Product p
CROSS APPLY STRING_SPLIT(p.Tags, ',') tags;
那么您的查询变为:
SELECT
p.Id,
p.Title,
tags.TagName
FROM Product p
CROSS APPLY (
SELECT
TagName = STRING_AGG(t.Title, ',')
FROM ProductTags pt
INNER JOIN Tag t ON pt.TagId = t.id
WHERE pt.ProductId = p.Id
) tags;