Как объединить несколько таблиц, одну таблицу в качестве динамических столбцов и другую таблицу в качестве значений этих столбцов - PullRequest
0 голосов
/ 14 января 2019

Я новичок в SQL Server Pivot, и я пытаюсь решить проблему, в которой мне нужно вывести следующие таблицы в одну таблицу, которая включает значения, основанные на столбцах одной таблицы

Вот мои столы

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     

1 Ответ

0 голосов
/ 15 января 2019

Али, вот пример, который, по крайней мере, поможет вам начать. В 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, как показано в моем примере, вам нужно будет знать все значения (Invoice, Due Date и т.д. ...), которые станут заголовками столбцов. Основываясь на ваших настройках, я думаю, что это может быть не так, поэтому вы будете вынуждены прибегнуть к технике, которая создает и выполняет динамический оператор PIVOT для вас в OUTER APPLY.

Вы также можете рассмотреть возможность использования ТАБЛИЦЫ-ЗНАЧЕННОЙ ФУНКЦИИ, которая выполняет работу PIVOT, к которой затем можно присоединиться по сравнению с OUTER APPLY.

У вас есть несколько вариантов, но, надеюсь, это поможет вам быстрее начать думать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...