2012-07-02 19 views
1

我在數據庫中有兩個表。第一個表tblTracker包含許多列,但特別感興趣的列被稱爲siteAdmin,並且該列中的每一行都可以包含多個像21457, 21456這樣的5位數字的登錄ID,或者只有一個像21444。下表users包含像LoginID,fnamelname這樣的列。T-SQL查詢,字段中的多個值

我希望能夠做到的是將tblTracker.siteAdmin中包含的登錄ID和用戶返回fname + lname。我可以成功做到這一點時,只有一個loginID在行中,如21444但我不知道如何做到這一點,當有不止一個像21457, 21456

這裏是我使用的時候有在該列一個登錄ID

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

但是當它試圖在它

加入 siteAdmin與多個 LoginID這不起作用的SQL語句

謝謝!

+0

是否有多個值在一個列或只有一列,請不要告訴我你有多個值用逗號分隔? – JonH

+0

siteAdmin是一個單列,多個值之間用逗號分隔。它不是理想的,但它是我繼承的。我不能通過改變事物在數據庫中的存儲方式來改變原因,因爲這會破壞上帝知道的內容。 – Mike

+0

感謝您的評論。我不知道鐘聲和口哨對人們很重要,我會確保在未來接受答案。 – Mike

回答

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) 

一旦表中設置了數字,創建此分割功能:

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,,,') 

OUTPUT:

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

(6 row(s) affected) 

你現在可以使用交叉適用於每排在表格中分爲:

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 

OUTPUT:

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) 
+0

謝謝!那爲我做了詭計。 – Mike