PIVOT具有动态列和JOINS 5+表

问题描述 投票:1回答:2

这是我之前发布的问题的扩展,可以在这里找到:Previous Question

现在我还有2个表连接到ProfileFan跟踪风扇的活动(ProfileFan)。

Table Fan
-----------------------
| FanId | Name | Info |
-----------------------
| 17111 | Fan1 | Info1|
-----------------------  
| 17112 | Fan2 | Info2|
-----------------------

    Table ProfileFan m:1 Fan FanId(FK)
    -----------------------------------
    | Id | LinkedInProfileId | FanId |
    -----------------------------------
    | 1111    | 1          | 17111   |
    ---------------------------------
    | 1112    | 2          | 17111   |
    ----------------------------------
    | 1113    | 1          | 17112   |
    ----------------------------------
    | 1114    | 2          | 17112   |
    ----------------------------------

    Table LinkedInProfile
    --------------------------
    | Id   | Name    | Client |
    --------------------------
    | 1    | Linked1 | Client1|
    --------------------------
    | 2    | Linked2 | Client1|
    --------------------------

    Table FanActivity m:1 ProfileFan via ProfileFanId (FK)
    ------------------------------------------------
    | Id   | Created    | ProfileFanId | ActivityId |
    -------------------------------------------------
    | 1    | 2019-01-05 |    17111     |     1      |
    -------------------------------------------------
    | 2    | 2019-01-05 |    17111     |     2      |
    -------------------------------------------------
    | 3    | 2019-01-05 |    17112     |     3     |
    -------------------------------------------------
    | 4    | 2019-01-05 |    17112     |     4      |
    -------------------------------------------------

    Table Activity Id(PK) 
    --------------------
    | Id   | Name        | 
    ---------------------
    | 1    | ConAccepted |
    ---------------------
    | 2    | Message     |
    ---------------------
    | 3    | LikesContent |  
    ----------------------
    | 4    | JoinsGroup  |        
    ----------------------

    Table DeliveryActions m:1 ProfileFan via ProfileFanId (FK)
    ------------------------------------------------------
    | Id   | LoggedAt   | ProfileFanId | DeliveryActionId |
    -------------------------------------------------------
    | 1    | 2019-01-05 |    17111     |     1            |
    ------------------------------------------------------
    | 2    | 2019-01-05 |    17111     |     2            |
    ------------------------------------------------------
    | 3    | 2019-01-05 |    17112     |     3            |
    ------------------------------------------------------
    | 4    | 2019-01-05 |    17112     |     4            |
    ------------------------------------------------------

    Table DeliveryAction Id(PK) 
    ------------------------
    | Id   | Name           | 
    ------------------------
    | 1    | M1             |
    ------------------------
    | 2    | M2             |
    ------------------------
    | 3    | M3             |  
    ------------------------
    | 4    | M4             |        
    ------------------------

查询的输出应如下所示。

    -------------------------------------------------------------------------------------------------------------------------------------------------------
    | Name | Info  | LinkedInProfile1| LinkedInProfile2 | Client |ConAccepted | Message | LikesContent | JoinsGroup |     M1     |    M2     |      M3     |     M4     |
    ---------------------------------------------------------------------------------------------------------------------------------------------------
    | Name1 | Info1|  Linked1(1111)  | Linked2(1112)   | Client1 | 2019-01-05 | 2019-01-06 | 2019-01-07 | 2019-01-08 | 2019-01-09 | 2019-01-05 |2019-01-06 | 2019-01-07 |
    ---------------------------------------------------------------------------------------------------------------------------------------------------
    | Name2 | Info2|  Linked1(1113)  | Linked2(1114)    | Client1 |2019-01-05 | 2019-01-06 | 2019-01-07 | 2019-01-08 | 2019-01-09 | 2019-01-05 |2019-01-05 | 2019-01-0 |
    ---------------------------------------------------------------------------------------------------------------------------------------------------

我需要在一行中插入一个粉丝的查询数据,而不是为每个给我连接的行插入多个。到目前为止,stackoverflow用户建议我通过使用PIVOT和动态查询来解决方案,仅针对LinkedInProfile。

我也在这里创建了一个模拟https://rextester.com/live/NYYK67222

我需要在FanActivities和DeliveryActions表上进行适当的连接到目前为止的联接之上,并将数据放在每个FAN的一行中!

所以1 FAN是2 LinkedInProfiles - >这创建了2个ProfileFansId。所有的profileFans都有很多FanActivities和很多DeliveryActions。

我知道我需要在这里使用带有动态列的PIVOT。但它对我来说都是新的。

sql sql-server pivot outer-join dynamic-columns
2个回答
2
投票

由于您所需的结果与rexter上的示例数据不同,我只修改了FanActivities和DeliveryActions表中的一些数据。

CREATE TABLE #Fan (FanId INT, Name VARCHAR(100), Info VARCHAR(100));

INSERT INTO #Fan
VALUES (17111, 'Fan1', 'Info1'), (17112, 'Fan2', 'Info2');

CREATE TABLE #LinkedInProfile (Id INT, Name VARCHAR(100), Client VARCHAR(100));

INSERT INTO #LinkedInProfile
VALUES (1, 'Linked1', 'Client1'), (2, 'Linked2', 'Client1');

CREATE TABLE #ProfileFan (Id INT, ProfileId INT, FanId INT);

INSERT INTO #ProfileFan
VALUES (1111, 1, 17111), (1112, 2, 17111), (1113, 1, 17112), (1114, 2, 17112);

CREATE TABLE #Activities (Id INT, Name VARCHAR(100));

INSERT INTO #Activities
VALUES (1, 'ConAccepted'), (2, 'Message'), (3, 'LikesContent'), (4, 'JoinsGroup');

CREATE TABLE #FanActivities (Id INT, Created VARCHAR(100), ProfileFanId INT
                           , ActivityId INT);

INSERT INTO #FanActivities
VALUES 
  (1, '2019-01-05', 1111, 1), (1, '2019-01-05', 1111, 2)
, (1, '2019-01-05', 1112, 3), (1, '2019-01-05', 1111, 4)
, (1, '2019-01-05', 1113, 1), (1, '2019-01-05', 1113, 2)
, (1, '2019-01-05', 1114, 3), (1, '2019-01-05', 1113, 4);

CREATE TABLE #DeliveryAction (Id INT, Name VARCHAR(100));

INSERT INTO #DeliveryAction
VALUES (1, 'M1'), (2, 'M2'), (3, 'M3'), (4, 'M4');

CREATE TABLE #DeliveryActions (Id INT, Created VARCHAR(100), ProfileFanId INT
                            , ActivityId INT);

INSERT INTO #DeliveryActions
VALUES 
  (1, '2019-01-05', 1111, 1), (1, '2019-01-05', 1111, 2)
, (1, '2019-01-05', 1112, 3), (1, '2019-01-05', 1111, 4)
, (1, '2019-01-05', 1113, 1), (1, '2019-01-05', 1113, 2)
, (1, '2019-01-05', 1114, 3), (1, '2019-01-05', 1113, 4);

你的查询将是

;WITH CTE AS(
SELECT F.FanId,F.Name AS FANNAME,F.Info 
,CONCAT(lip.Name,'(',pf.Id,')') AS LINKEDPROFILE
,CONCAT('#LinkedInProfile',pf.ProfileId) as LipId 
, LIP.Client
,FACT.Name AS FANACTIVITY, FA.Created FANACTIVITYDATE
,DA.Name AS DELVACTIVITY, DAS.Created DELVACTIVITYDATE
FROM #Fan F
LEFT JOIN #ProfileFan pf ON f.FanId = pf.FanId
LEFT JOIN #LinkedInProfile lip ON pf.ProfileId = lip.Id
LEFT JOIN #FanActivities FA ON PF.Id = FA.ProfileFanId
LEFT JOIN #ActivitieS FACT ON FACT.Id = FA.ActivityId
LEFT JOIN #DeliveryActions DAS ON PF.Id = DAS.ProfileFanId
LEFT JOIN #DeliveryAction DA ON DAS.ActivityId = DA.ID
)
SELECT FANNAME, Info, Client
,[#LinkedInProfile1],[#LinkedInProfile2]
,[ConAccepted],[Message],[LikesContent],[JoinsGroup]
,[M1],[M2],[M3],[M4] FROM (
SELECT  FANNAME, Info, Client,KEYS,VALUE
FROM CTE
CROSS APPLY (
    VALUES (LipId, LINKEDPROFILE)
    , (FANACTIVITY,FANACTIVITYDATE)
    ,(DELVACTIVITY,DELVACTIVITYDATE)
    )AS TAB(KEYS,VALUE)
)AS A
PIVOT
(
    MAX(VALUE) FOR KEYS IN ([#LinkedInProfile1],[#LinkedInProfile2]
    ,[ConAccepted],[Message],[LikesContent],[JoinsGroup]
    ,[M1],[M2],[M3],[M4])
)PV

结果我得到了

+---------+-------+---------+-------------------+-------------------+-------------+------------+--------------+------------+------------+------------+------------+------------+
| FANNAME | Info  | Client  | #LinkedInProfile1 | #LinkedInProfile2 | ConAccepted |  Message   | LikesContent | JoinsGroup |     M1     |     M2     |     M3     |     M4     |
+---------+-------+---------+-------------------+-------------------+-------------+------------+--------------+------------+------------+------------+------------+------------+
| Fan1    | Info1 | Client1 | Linked1(1111)     | Linked2(1112)     | 2019-01-05  | 2019-01-05 | 2019-01-05   | 2019-01-05 | 2019-01-05 | 2019-01-05 | 2019-01-05 | 2019-01-05 |
| Fan2    | Info2 | Client1 | Linked1(1113)     | Linked2(1114)     | 2019-01-05  | 2019-01-05 | 2019-01-05   | 2019-01-05 | 2019-01-05 | 2019-01-05 | 2019-01-05 | 2019-01-05 |
+---------+-------+---------+-------------------+-------------------+-------------+------------+--------------+------------+------------+------------+------------+------------+

1
投票

帖子中的示例代码与您的rextester示例之间存在一些差异(例如,帖子中的DeliveryActions.ProfileFanId似乎引用Fan.FanId,但在rextester示例中它引用了ProfileFan.Id)。我的答案是基于你的rextester样本。

我个人的偏好是不做多个支点,如果我不需要,而是使用交叉表查询......我更容易看到和理解而不是有多层支点。

你可以在rextester here中看到这个。

SELECT 
    f.Name
    ,f.Info
    ,LinkedInProfile1 = MAX(CASE WHEN pf.ProfileId  = 1 THEN CONCAT(lip.Name,'(',pf.Id,')') END)
    ,LinkedInProfile2 = MAX(CASE WHEN pf.ProfileId  = 2 THEN CONCAT(lip.Name,'(',pf.Id,')') END)
    ,lip.Client
    ,ConAccepted = MAX(CASE WHEN a.Name = 'ConAccepted' THEN fa.Created END)
    ,Message = MAX(CASE WHEN a.Name = 'Message ' THEN fa.Created END)
    ,LikesContent = MAX(CASE WHEN a.Name = 'LikesContent ' THEN fa.Created END)
    ,JoinsGroup = MAX(CASE WHEN a.Name = 'JoinsGroup ' THEN fa.Created END)
    ,M1 = MAX(CASE WHEN da.Name = 'M1' THEN das.Created END)
    ,M2 = MAX(CASE WHEN da.Name = 'M2 ' THEN das.Created END)
    ,M3 = MAX(CASE WHEN da.Name = 'M3 ' THEN das.Created END)
    ,M4 = MAX(CASE WHEN da.Name = 'M4 ' THEN das.Created END)
FROM fan f
JOIN dbo.ProfileFan pf
    ON pf.FanId = f.FanId
JOIN dbo.LinkedInProfile lip
    ON lip.Id = pf.ProfileId
JOIN dbo.FanActivities fa
    ON fa.ProfileFanId = pf.Id
JOIN Activities a
    ON a.Id = fa.ActivityId
JOIN dbo.DeliveryActions das
    ON das.ProfileFanId = pf.Id
JOIN dbo.DeliveryAction da
    ON da.Id = das.ActivityId
GROUP BY f.Name, f.info, lip.Client
© www.soinside.com 2019 - 2024. All rights reserved.