T-SQL查询组合可用并在一行中选择

时间:2015-01-21 23:45:26

标签: sql-server

我有两张桌子。一个是library表,另一个是关系表(见下文)。 table1列出了所有可能的邮件列表(或其他),table2表示联系人' John'的列表在1,3,4中列出。 是否可以编写查询以将所有可用的邮件列表项和所选项一行中获取?你能帮忙吗?

输出一行:

John,    A:1,  B:0,  C:1,  D:1,  E:0
Mary,    A:1,  B:0,  C:0,  D:0,  E:1

table1(库表)

Id  Name
1   A
2   B
3   C
4   D
5   E

table2(关系表)

contact Mail-id
John    1
John    3
John    4
Mary    1
Mary    5

1 个答案:

答案 0 :(得分:1)

将table2中的不同联系人与table1交叉连接,然后将结果与table2

连接起来

如果您希望将邮件列表放在以逗号分隔的单个列中,请使用for xml path()技巧。试试这个。

;WITH cte
     AS (SELECT b.contact,
                a.NAME + CASE WHEN c.[Mail-id] IS NOT NULL THEN ':1' ELSE ':0' END AS aval_mailinglist
         FROM   tab1e1 a
                CROSS JOIN (SELECT DISTINCT contact
                            FROM   table2) b
                LEFT JOIN table2 c
                       ON a.Id = c.[Mail-id]
                       and b.contact=c.contact)
SELECT contact,
       stuff((SELECT ',' + aval_mailinglist
        FROM   cte b
        WHERE  a.contact = b.contact
        FOR xml path('')),1,1,'') Mailing_list
FROM   cte a 
group by contact

如果您希望将结果放在不同的列中,请使用Pivot

DECLARE @cols VARCHAR(max)='',
        @sql  NVARCHAR(max)

SELECT @cols += NAME
FROM  (SELECT DISTINCT Quotename(Isnull(NAME, '')) + ',' NAME
       FROM   table1)a

SELECT @cols = LEFT(@cols, Len(@cols) - 1)

PRINT @cols

SET @sql=';WITH cte
     AS (SELECT b.contact,
                a.NAME + CASE WHEN c.[Mail-id] IS NOT NULL THEN '':1'' ELSE '':0'' END AS aval_mailinglist,
                a.name
         FROM   table1 a
                CROSS JOIN (SELECT DISTINCT contact
                            FROM   table2) b
                LEFT JOIN table2 c
                       ON a.Id = c.[Mail-id]
                       and b.contact=c.contact)

SELECT *
FROM   cte a 
pivot (max(aval_mailinglist) for name in ('
         + @cols + ') ) piv'

--print @sql
EXEC Sp_executesql @sql 

SQLFIDDLE DEMO