我是SQL Server枢纽的新手,我试图解决一个问题,我需要将以下表输出到一个包含基于一个表的列的值的表中
这是我的桌子
ContactGroup
Title ID
---------- -----------
Group A 1
ContactsInGroups
ContactId GroupId
----------- -----------
1 1
2 1
3 1
ContactVariables
ID Name GroupId Order
----------- ---------- ----------- ------
1 Invoice 1 1
2 Due Date 1 1
ContactsVariablesValues
ContactVariableId ContactId Value
----------------- ----------- -----
1 1 600
所需的输出
GroupId ContactId Invoice Due Date
----------- ----------- ----------- -----------
1 1 600 NULL
1 2 NULL NULL
1 3 NULL NULL
答案 0 :(得分:1)
Ali,这是一个至少可以帮助您入门的示例。您可以在SSMS中运行以下命令。
创建一些表变量并插入示例数据。
DECLARE @ContactGroup TABLE ( id INT, title VARCHAR(50) );
INSERT INTO @ContactGroup ( id, title ) VALUES ( 1, 'Group A' );
DECLARE @ContactsInGroup TABLE ( ContactID INT, GroupID INT );
INSERT INTO @ContactsInGroup ( ContactID, GroupID ) VALUES ( 1, 1 ), ( 2, 1 ), ( 3, 1 );
DECLARE @ContactVariables TABLE ( id INT, [name] VARCHAR(50), GroupID INT, [Order] INT );
INSERT INTO @ContactVariables ( id, [name], GroupID, [Order] ) VALUES ( 1, 'Invoice', 1, 1 ), ( 2, 'Due Date', 1, 1 );
DECLARE @ContactsVariablesValues TABLE ( ContactVariableID INT, ContactID INT, [value] INT );
INSERT INTO @ContactsVariablesValues ( ContactVariableID, ContactID, [value] ) VALUES ( 1, 1, 600 );
然后按以下方式查询数据:
SELECT
ContactGroup.id AS GroupID
, ContactsInGroup.ContactID
, ContactVars.Invoice
, ContactVars.[Due Date]
FROM @ContactGroup AS ContactGroup
INNER JOIN @ContactsInGroup AS ContactsInGroup
ON ContactGroup.id = ContactsInGroup.GroupID
OUTER APPLY (
SELECT
[Invoice], [Due Date]
FROM (
SELECT
Vars.[name]
, Vals.[value]
FROM @ContactVariables AS Vars
LEFT OUTER JOIN @ContactsVariablesValues Vals
ON Vars.id = Vals.ContactVariableID
WHERE
Vars.GroupID = 1
AND Vals.ContactID = ContactsInGroup.ContactID
) AS ContactData
PIVOT (
MIN( [value] )
FOR [name] IN (
[Invoice], [Due Date]
)
) AS pvt
) AS ContactVars
ORDER BY
ContactGroup.id, ContactsInGroup.ContactID;
返回哪个:
+---------+-----------+---------+----------+
| GroupID | ContactID | Invoice | Due Date |
+---------+-----------+---------+----------+
| 1 | 1 | 600 | NULL |
| 1 | 2 | NULL | NULL |
| 1 | 3 | NULL | NULL |
+---------+-----------+---------+----------+
注意事项
这里的“魔术”在外部应用中。这使我们可以基于返回的主要数据(在这种情况下为GroupID和ContactID)查询数据的子集。 OUTER APPLY还将返回您希望的具有NULL值的行。
您将在这里遇到一些挑战,即要使用我的示例中所示的PIVOT,您将需要知道将成为列标题的所有值(发票,到期日期等)。根据您的设置,我认为情况可能并非如此,因此您将不得不采用一种在OUTER APPLY中为您创建并执行动态PIVOT语句的技术。
您还可以考虑使用TABLE VALUED FUNCTION来完成PIVOT的工作,然后可以与外部应用程序进行联接。
您有几种选择,但是希望这可以帮助您快速思考。