1

データベースに2つのテーブルがあります。最初のテーブルtblTrackerには多くの列が含まれていますが、特に関心のある列が呼び出されsiteAdmin、その列の各行には、のような5桁21457, 21456または1つのような複数のloginIDを含めることができます21444。次のテーブルには、、、、などのusers列が含まれています。LoginIDfnamelname

私ができるようにしたいのは、ユーザーに含まれているloginIDを取得してユーザーからtblTracker.siteAdmin返すfname + lnameことです。loginIDのような行が1つしかない場合はこれを正常に実行できますが、の21444ようなものが複数ある場合はこれを実行する方法がわかりません21457, 21456

その列にloginIDが1つある場合に使用するSQLステートメントは次のとおりです

SELECT b.FName + '' '' + b.LName AS siteAdminName,
FROM tblTracker a
LEFT OUTER JOIN users b ON a.siteAdmin= b.Login_Id

siteAdminただし、複数のを含むに参加しようとすると、これは機能しませLoginID

ありがとう!

4

1 に答える 1

1

TSQLで文字列を分割するには、数値テーブルアプローチを使用します

この方法を機能させるには、次の1つのタイムテーブルの設定を行う必要があります。

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)
于 2012-07-03T11:50:04.130 に答える