Dynamically interpolate extra rows in SQL query

南楼画角 提交于 2019-12-14 03:12:56

问题


I am using SQL Server 2012. I have the following query:

SELECT p.PortfolioGroupID, p.PortfolioGroupCode, p.DisplayOrder, p.MemberCode, m.ContactCode, m.Custom01, 'Separator' As 'PDFType'
  FROM [APXFirm].[AdvApp].[vPortfolioGroupMemberFlattened] p
  LEFT OUTER JOIN [APXFirm].[AdvApp].[vPortfolioInterestedParty] m
  on p.memberid = m.PortfolioID
WHERE m.ContactCode is not null
and p.PortfolioGroupCode like '%_Package'
  order by m.ContactCode, p.MemberCode

Current Result Set

PortfolioGroupID    PortfolioGroupCode  DisplayOrder    MemberCode  ContactCode Custom01    PDFType
11224   Test1_Package   677 test1   recipient1_ind  DVAAnnual   Separator
11224   Test1_Package   730 test2   recipient1_ind  DVAAnnual   Separator
11221   Test2_Package   1825    test3   recipient2_ind  DVAAnnual   Separator
11221   Test2_Package   1826    test4   recipient2_ind  DVAAnnual   Separator
11221   Test2_Package   1827    test5   recipient2_ind  DVAAnnual   Separator

Desired Result Set

PortfolioGroupID    PortfolioGroupCode  DisplayOrder    MemberCode  ContactCode Custom01    PDFType
11224   Test1_Package   677 test1   recipient1_ind  DVAAnnual   Cover
11224   Test1_Package   677 test1   recipient1_ind  DVAAnnual   Separator
11224   Test1_Package   677 test1   recipient1_ind  DVAAnnual   Report
11224   Test1_Package   730 test2   recipient1_ind  DVAAnnual   Separator
11224   Test1_Package   730 test2   recipient1_ind  DVAAnnual   Report
11221   Test2_Package   1825    test3   recipient2_ind  DVAAnnual   Cover
11221   Test2_Package   1825    test3   recipient2_ind  DVAAnnual   Separator
11221   Test2_Package   1825    test3   recipient2_ind  DVAAnnual   Report
11221   Test2_Package   1826    test4   recipient2_ind  DVAAnnual   Separator
11221   Test2_Package   1826    test4   recipient2_ind  DVAAnnual   Report
11221   Test2_Package   1827    test5   recipient2_ind  DVAAnnual   Separator
11221   Test2_Package   1827    test5   recipient2_ind  DVAAnnual   Report

For every instance of a group indicated by a new PortfolioGroupID in the PortfolioGroupID column. (In this example there are 2 groups 11224 and 11221) I need one row added as the first row that has the word Cover before where I have placed the word separator. All other columns are identical to the row it is placed before.

For every row in the group I need to interpolate/alternate a row with the word Report after the row where I placed the word separator. All other columns are identical to the row it is placed after.

If for some reason it's easier to place the word Separator before Report I could change the hard-coded value of Separator to Report.

Is this possible?


回答1:


The first step would be to add a RowNumber column to identify the first row for each PorfoilioGroupID:

SELECT  p.PortfolioGroupID, 
        p.PortfolioGroupCode, 
        p.DisplayOrder, 
        p.MemberCode, 
        m.ContactCode, 
        m.Custom01, 
        RowNumber = ROW_NUMBER() OVER(PARTITION BY P.PortfolioGroupID ORDER BY m.ContactCode, p.MemberCode)
FROM    [APXFirm].[AdvApp].[vPortfolioGroupMemberFlattened] p
        LEFT OUTER JOIN [APXFirm].[AdvApp].[vPortfolioInterestedParty] m
            ON p.memberid = m.PortfolioID
WHERE   m.ContactCode is not null
AND     p.PortfolioGroupCode like '%_Package'
ORDER BY m.ContactCode, p.MemberCode;

Then you can join your results set with a table valued constructor with your 3 values (Cover, Sperator, Report), and just add a where clause to ensure 'Cover' only appears for the first row:

WITH Data AS
(   SELECT  p.PortfolioGroupID, 
            p.PortfolioGroupCode, 
            p.DisplayOrder, 
            p.MemberCode, 
            m.ContactCode, 
            m.Custom01, 
            RowNumber = ROW_NUMBER() OVER(PARTITION BY P.PortfolioGroupID ORDER BY p.DisplayOrder)
    FROM    [APXFirm].[AdvApp].[vPortfolioGroupMemberFlattened] p
            LEFT OUTER JOIN [APXFirm].[AdvApp].[vPortfolioInterestedParty] m
                ON p.memberid = m.PortfolioID
    WHERE   m.ContactCode is not null
    AND     p.PortfolioGroupCode like '%_Package'
)
SELECT  d.PortfolioGroupID, 
        d.PortfolioGroupCode, 
        d.DisplayOrder, 
        d.MemberCode, 
        d.ContactCode, 
        d.Custom01, 
        t.PDFType
FROM    Data d
        CROSS JOIN 
        (   VALUES
                ('Cover'),
                ('Seperator'),
                ('Report')
        ) t (PDFType)
WHERE   d.RowNumber = 1
OR      t.PDFType != 'Cover'
ORDER BY ContactCode, MemberCode;

Example on SQL Fiddle



来源:https://stackoverflow.com/questions/20763803/dynamically-interpolate-extra-rows-in-sql-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!