我有两个表:1. AuthorMaster和2. Books
AuthorMaster
----------------
ID Name
1 ABC
2 XYZ
3 PQR
Books
----------------
ID BookName AuthorIds
1 MATHEMATICS 2,3
2 Briar Queen 1,3
I need output like
ID BookName AuthorNames
1 MATHEMATICS XYZ, PQR
2 Briar Queen ABC, PQR
我试图创建一个单独的存储过程来获取作者姓名:
DECLARE @Query VARCHAR(MAX)
declare @t table(AuthorNames varchar(max))
SET @Query = 'DECLARE @AuthorNames VARCHAR(MAX); SELECT @AuthorNames = COALESCE( @AuthorNames + '', '', '''') + AuthorName FROM AuthorMasters WHERE AuthorId IN (' + @IDs + ') AND ISNULL(IsDelete, 0) = 0; SELECT @AuthorNames'
INSERT INTO @t
Execute(@Query)
SELECT @AuthorNames = AuthorNames FROM @t
但是我不能在选择语句中执行它。
SELECT ID, BookName, <how to call sp where i can pass Books.AuthorIds?> FROM Books
答案 0 :(得分:1)
在SQL Server 2017之前,string_agg
最终作为内置函数引入时,
连接不同行中的字符串的常见方法是使用here所示的stuff
和for xml path('')
的组合。
现在,让我们创建并填充示例表(请在您将来的问题中为我们保存此步骤):
CREATE TABLE AuthorMaster
(
id int,
Name char(3)
);
INSERT INTO AuthorMaster (ID, Name) VALUES
(1, 'ABC'),
(2, 'XYZ'),
(3, 'PQR');
CREATE TABLE Books
(
ID int,
BookName varchar(100),
AuthorIds varchar(100)
);
INSERT INTO Books (ID, BookName, AuthorIds) VALUES
(1, 'MATHEMATICS', '2,3'),
(2, 'Briar Queen', '1,3');
此设计的问题在于,与其创建BookToAuthor
桥接表来创建多对多关系,
数据库设计者使用了一个糟糕的主意,决定将作者ID作为分隔字符串存储在数据库中。 (Why is this such a terrible idea?)
要克服此问题,我们需要分割此定界字符串。 las,在SQL Server 2016之前,当最终引入string_split
时,您必须使用用户定义的函数来分隔定界字符串。
Aaron Bertrand在2012年发表了一篇名为Split strings the right way – or the next best way的文章,他比较了不同的字符串拆分功能。
我在该答案中使用了他的文章中的一个示例-SplitStrings_XML
函数:
CREATE FUNCTION dbo.SplitStrings_XML
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
GO
现在,我们有了示例数据和字符串拆分功能,让我们开始查询。在作者的名字上使用字符串聚合查询,这些ID在AuthorIds列中,然后交叉应用以将其绑定到books表中, 这是我想出的查询:
SELECT ID,
BookName,
AuthorsNames
FROM Books
CROSS APPLY
(
SELECT STUFF(
(
SELECT ','+ Name
FROM AuthorMaster
WHERE Id IN
(
SELECT Item
FROM dbo.SplitStrings_XML(AuthorIds, ',')
)
FOR XML PATH('')
), 1, 1, '') As AuthorsNames
) As Names
这是结果:
ID BookName AuthorsNames
1 MATHEMATICS XYZ,PQR
2 Briar Queen ABC,PQR