T-SQL查询,字段中的多个值

时间:2012-07-02 18:55:42

标签: tsql

我在数据库中有两个表。第一个表tblTracker包含许多列,但特别感兴趣的列称为siteAdmin,该列中的每一行可以包含5个数字的多个loginID,如21457, 21456或只有21444之类的users。 1}}。下一个表格LoginID包含fnamelnametblTracker.siteAdmin等列。

我希望能够执行fname + lname中包含的loginID并从用户返回loginID。如果21444行中只有一个21457, 21456,我可以成功执行此操作,但当有多个SELECT b.FName + '' '' + b.LName AS siteAdminName, FROM tblTracker a LEFT OUTER JOIN users b ON a.siteAdmin= b.Login_Id 时,我无法弄清楚如何执行此操作。

这是我在该列中有一个loginID时使用的SQL语句

siteAdmin

但是当它尝试加入LoginID并且其中包含多个{{1}}时,这不起作用

谢谢!

1 个答案:

答案 0 :(得分:1)

I prefer the number table approach to split a string in TSQL

要使此方法起作用,您需要执行以下一次性表设置:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

设置Numbers表后,创建此拆分功能:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(

    ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''

);
GO 

您现在可以轻松地将CSV字符串拆分为表格并加入其中:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,')

输出:

ListValue
-----------------------
1
2
3
4
5
6777

(6 row(s) affected)

您现在可以使用CROSS APPLY来分割表格中的每一行,如:

DECLARE @users table (LoginID int, fname varchar(5), lname varchar(5))
INSERT INTO @users VALUES (1, 'Sam', 'Jones')
INSERT INTO @users VALUES (2, 'Don', 'Smith')
INSERT INTO @users VALUES (3, 'Joe', 'Doe')
INSERT INTO @users VALUES (4, 'Tim', 'White')
INSERT INTO @users VALUES (5, 'Matt', 'Davis')
INSERT INTO @users VALUES (15,'Sue', 'Me')

DECLARE @tblTracker  table (RowID int, siteAdmin varchar(50))
INSERT INTO @tblTracker VALUES (1,'1,2,3')
INSERT INTO @tblTracker VALUES (2,'2,3,4')
INSERT INTO @tblTracker VALUES (3,'1,5')
INSERT INTO @tblTracker VALUES (4,'1')
INSERT INTO @tblTracker VALUES (5,'5')
INSERT INTO @tblTracker VALUES (6,'')
INSERT INTO @tblTracker VALUES (7,'8,9,10')
INSERT INTO @tblTracker VALUES (8,'1,15,3,4,5')

SELECT
    t.RowID, u.LoginID, u.fname+' '+u.lname AS YourAdmin
    FROM @tblTracker                                     t
        CROSS APPLY dbo.FN_ListToTable(',',t.siteAdmin)  st
        LEFT OUTER JOIN @users                           u ON st.ListValue=u.LoginID --to get all rows even if missing siteAdmin
        --INNER JOIN @users                                u ON st.ListValue=u.LoginID  --to remove rows without any siteAdmin
    ORDER BY t.RowID,u.fname,u.lname

输出:

RowID       LoginID     YourAdmin
----------- ----------- -----------
1           2           Don Smith
1           3           Joe Doe
1           1           Sam Jones
2           2           Don Smith
2           3           Joe Doe
2           4           Tim White
3           5           Matt Davis
3           1           Sam Jones
4           1           Sam Jones
5           5           Matt Davis
7           NULL        NULL
7           NULL        NULL
7           NULL        NULL
8           3           Joe Doe
8           5           Matt Davis
8           1           Sam Jones
8           15          Sue Me
8           4           Tim White

(18 row(s) affected)