微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用于搜索和填充多行的 SQL 服务器查询

如何解决用于搜索和填充多行的 SQL 服务器查询

我有这样的表employee_table

org     employeeid (int)    firstname   lastname
1234    56788934            Suresh      Raina
1234    56793904            Virat       Kohli

然后我有 project_table 就像这样

Project     members (varchar)
A123        56788934,56793900

现在我需要像这样在一行中获取相应的员工姓名和东西。

Project     members (varchar)
A123        Suresh Raina,Virat Kohli

我在下面写了一个不起作用的查询。请帮忙。

SELECT project,(
            SELECT   message_text = Stuff(
                     (
                            SELECT ',' + Concat(firstname,' ',lastname)
                            FROM   employee_table t1
                            WHERE  t1.org = t2.org
                            AND    CONVERT(VARCHAR,t1.userid) IN (Concat('''',Replace(pt.members,',''','''),'''')) --adding single quotes at start and end of each number
                                   FOR xml path ('')),1,'')
            FROM     employee_table t2
            WHERE    t2.userid IN
            group BY org;) FROM project_table pt 

解决方法

这是 SQL Server 2017 以后的解决方案。

它使用了 SQL Server 2017 中可用的一对方便的函数:

  • STRING_SPLIT()
  • STRING_AGG()

方法 2 涵盖 SQL Server 2008 及更高版本的解决方案。

SQL

-- DDL and sample data population,start
DECLARE @employee TABLE (org INT,employeeid INT,firstname VARCHAR(20),lastname VARCHAR(30));
INSERT INTO @employee (org,employeeid,firstname,lastname) VALUES
(1234,56788934,'Suresh','Raina'),(1234,56793904,'Virat','Kohli');

DECLARE @project TABLE (project CHAR(4),members VARCHAR(MAX));
INSERT INTO @project (project,members) VALUES
('A123','56788934,56793904');
-- DDL and sample data population,end

-- Method #1,SQL Server 2017 onwards
SELECT p.project,STRING_AGG(CONCAT(e.firstname,SPACE(1),e.lastname),',') AS members
FROM @project AS p CROSS APPLY STRING_SPLIT(members,') AS s
    INNER JOIN @employee AS e ON s.value = e.employeeid
GROUP BY p.project;

-- Method #2,SQL Server 2008 onwards
DECLARE @separator CHAR(1) = ',';

;WITH rs AS
(
    SELECT *,TRY_CAST('<root><r><![CDATA[' + 
         REPLACE(members,@separator,']]></r><r><![CDATA[') + ']]></r></root>' AS XML) AS xmldata
    FROM @project
),cte AS 
(
    SELECT project,e.*
    FROM rs CROSS APPLY xmldata.nodes('/root/r/text()') AS t(c)
        INNER JOIN @employee AS e ON c.value('.','INT') = e.employeeid
)
SELECT project,STUFF((SELECT @separator + CAST(CONCAT(o.firstname,o.lastname) AS VARCHAR(30)) AS [text()]
         FROM cte AS O
         WHERE O.project = C.project 
         FOR XML PATH('')),1,NULL) AS Members
FROM cte AS c
GROUP BY project;

输出

+---------+---------------------------+
| project |          members          |
+---------+---------------------------+
| A123    | Suresh Raina,Virat Kohli |
+---------+---------------------------+

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。