Separate a column into its components based on another tableQuery to normalize table/combine row textHow to add/update a column with an incremented value and reset said value based on another column in SQLColumn Name in separate table SQL ServerSQL Server query problem when selecting data from child table based on column in parent tableWhy does a table of varchar(255) columns take up less space than an identical table using the correct data typesMerging table output into a column in another tableAdding an IF based comparison columnHow can I optimize this MYSQL Script For many Records?Implicit Conversion of VARCHAR Column to NVARCHAR does not cause expected table scanCheck and count if a column value is used in another column of same table

Computer name naming convention for security

When do flights get cancelled due to fog?

How many Jimmys can fit?

Decrease spacing between a bullet point and its subbullet point

Users forgotting to regenerate PDF before sending it

Category-theoretic treatment of diffs, patches and merging?

Wires do not connect in Circuitikz

Is homosexuality or bisexuality allowed for women?

Intern not wearing safety equipment; how could I have handled this differently?

How do you correct inclination at launch to ISS?

My professor has told me he will be the corresponding author. Will it hurt my future career?

Other Space Shuttle O-ring failures

Why the Cauchy Distribution is so useful?

Is it possible for a character at any level to cast all 44 Cantrips in one week without Magic Items?

What factors could lead to bishops establishing monastic armies?

Why does Trump want a citizenship question on the census?

How can I use my cell phone's light as a reading light?

This LM317 diagram doesn't make any sense to me

How should I ask for a "pint" in countries that use metric?

QR codes, do people use them?

Publishing papers seem natural to many, while I find it really hard to think novel stuff to pursue till publication. How to cope up with this?

What does "spinning upon the shoals" mean?

Who goes first? Person disembarking bus or the bicycle?

stuck in/at beta



Separate a column into its components based on another table


Query to normalize table/combine row textHow to add/update a column with an incremented value and reset said value based on another column in SQLColumn Name in separate table SQL ServerSQL Server query problem when selecting data from child table based on column in parent tableWhy does a table of varchar(255) columns take up less space than an identical table using the correct data typesMerging table output into a column in another tableAdding an IF based comparison columnHow can I optimize this MYSQL Script For many Records?Implicit Conversion of VARCHAR Column to NVARCHAR does not cause expected table scanCheck and count if a column value is used in another column of same table






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








2















I'm struggling with a very difficult and complicated query here and I need your help.



I have two tables as you can see below:



1) ACCOUNT1:(ATYPCODE int, ATYPDESC varchar(50), ATLASTFLAG varchar(50))


some example data of this table are:



ATYPCODE ATYPDESC ATLASTFLAG 
3000 A 0
19 B 0
1170 C 0
1178 D 1
4000 AA 0
18 BB 0
2020 CC 1


Column ATLASTFLAG shows whether this record is the last level .
Table number two is



2) ACCOUNT2:(ATYPCODE int, AGLTCODE varchar(50), AGLTLVL int)


some example data of this table are:



 ATYPCODE AGLTCODE AGLTLVL 
3000 3000 1
19 3000 19 2
1170 3000 191170 3
1178 3000 1911701178 4
4000 4000 1
18 4000 18 2
2020 4000 182020 3


Column ATYPCODE is exactly the same as ATYPCODE column in the first table.Column AGLTCODE is bult based on the concatenation of ATYPCODEcolumn as you can see. The point is that the second level added to the first level with two spaces . so we have 3000+space+space+19+Other_levels and we have to separate this column exactly with 4 characters.
and the column AGLTLVL shows the level of each ATYPCODE .



what we want to see as a result is this :



ATYPCODE AGLTCODE AGLTLVL ATYPCODE1 ATYPCODE2 ATYPCODE3 ATYPCODE4 ATYPDESC1 ATYPDESC2 ATYPDESC3 ATYPDESC4 


and values for each column



ATYPCODE = 1178 
AGLTCODE = 3000 1911701178
AGLTLVL = 4
ATYPCODE1 = 3000
ATYPCODE2 = 19
ATYPCODE3 = 1170
ATYPCODE4 = 1178
ATYPDESC1 = A
ATYPDESC2 = B
ATYPDESC3 = C
ATYPDESC4 = D


and also the next record is



ATYPCODE = 2020 
AGLTCODE = 4000 182020
AGLTLVL = 3
ATYPCODE1 = 4000
ATYPCODE2 = 18
ATYPCODE3 = 2020
ATYPCODE4 = 2020(last value is repeated)
ATYPDESC1 = AA
ATYPDESC2 = BB
ATYPDESC3 = CC
ATYPDESC4 = CC(Last Values is repeated)


as you can see some records have 4 levels and some have 3 levels
since the structure of the destination table is fixed,for those with 3 levels , last value ATYPCODE3 and ATYPDESC3should be repeated for columns ATYPCODE4 and ATYPDESC4 .



the only part of query I was able to write was this cause we only nees to store the last level and nothing comes to mind for the rest of the query



SELECT b.ATYPCODE , b.AGLTCODE , b.AGLTLVL
FROM ACCOUNT1 a inner join
ACCOUNT2 b on a.ATYPCODE = b.ATYPCODE
where a.ATLASTFLAG = 1









share|improve this question






























    2















    I'm struggling with a very difficult and complicated query here and I need your help.



    I have two tables as you can see below:



    1) ACCOUNT1:(ATYPCODE int, ATYPDESC varchar(50), ATLASTFLAG varchar(50))


    some example data of this table are:



    ATYPCODE ATYPDESC ATLASTFLAG 
    3000 A 0
    19 B 0
    1170 C 0
    1178 D 1
    4000 AA 0
    18 BB 0
    2020 CC 1


    Column ATLASTFLAG shows whether this record is the last level .
    Table number two is



    2) ACCOUNT2:(ATYPCODE int, AGLTCODE varchar(50), AGLTLVL int)


    some example data of this table are:



     ATYPCODE AGLTCODE AGLTLVL 
    3000 3000 1
    19 3000 19 2
    1170 3000 191170 3
    1178 3000 1911701178 4
    4000 4000 1
    18 4000 18 2
    2020 4000 182020 3


    Column ATYPCODE is exactly the same as ATYPCODE column in the first table.Column AGLTCODE is bult based on the concatenation of ATYPCODEcolumn as you can see. The point is that the second level added to the first level with two spaces . so we have 3000+space+space+19+Other_levels and we have to separate this column exactly with 4 characters.
    and the column AGLTLVL shows the level of each ATYPCODE .



    what we want to see as a result is this :



    ATYPCODE AGLTCODE AGLTLVL ATYPCODE1 ATYPCODE2 ATYPCODE3 ATYPCODE4 ATYPDESC1 ATYPDESC2 ATYPDESC3 ATYPDESC4 


    and values for each column



    ATYPCODE = 1178 
    AGLTCODE = 3000 1911701178
    AGLTLVL = 4
    ATYPCODE1 = 3000
    ATYPCODE2 = 19
    ATYPCODE3 = 1170
    ATYPCODE4 = 1178
    ATYPDESC1 = A
    ATYPDESC2 = B
    ATYPDESC3 = C
    ATYPDESC4 = D


    and also the next record is



    ATYPCODE = 2020 
    AGLTCODE = 4000 182020
    AGLTLVL = 3
    ATYPCODE1 = 4000
    ATYPCODE2 = 18
    ATYPCODE3 = 2020
    ATYPCODE4 = 2020(last value is repeated)
    ATYPDESC1 = AA
    ATYPDESC2 = BB
    ATYPDESC3 = CC
    ATYPDESC4 = CC(Last Values is repeated)


    as you can see some records have 4 levels and some have 3 levels
    since the structure of the destination table is fixed,for those with 3 levels , last value ATYPCODE3 and ATYPDESC3should be repeated for columns ATYPCODE4 and ATYPDESC4 .



    the only part of query I was able to write was this cause we only nees to store the last level and nothing comes to mind for the rest of the query



    SELECT b.ATYPCODE , b.AGLTCODE , b.AGLTLVL
    FROM ACCOUNT1 a inner join
    ACCOUNT2 b on a.ATYPCODE = b.ATYPCODE
    where a.ATLASTFLAG = 1









    share|improve this question


























      2












      2








      2


      1






      I'm struggling with a very difficult and complicated query here and I need your help.



      I have two tables as you can see below:



      1) ACCOUNT1:(ATYPCODE int, ATYPDESC varchar(50), ATLASTFLAG varchar(50))


      some example data of this table are:



      ATYPCODE ATYPDESC ATLASTFLAG 
      3000 A 0
      19 B 0
      1170 C 0
      1178 D 1
      4000 AA 0
      18 BB 0
      2020 CC 1


      Column ATLASTFLAG shows whether this record is the last level .
      Table number two is



      2) ACCOUNT2:(ATYPCODE int, AGLTCODE varchar(50), AGLTLVL int)


      some example data of this table are:



       ATYPCODE AGLTCODE AGLTLVL 
      3000 3000 1
      19 3000 19 2
      1170 3000 191170 3
      1178 3000 1911701178 4
      4000 4000 1
      18 4000 18 2
      2020 4000 182020 3


      Column ATYPCODE is exactly the same as ATYPCODE column in the first table.Column AGLTCODE is bult based on the concatenation of ATYPCODEcolumn as you can see. The point is that the second level added to the first level with two spaces . so we have 3000+space+space+19+Other_levels and we have to separate this column exactly with 4 characters.
      and the column AGLTLVL shows the level of each ATYPCODE .



      what we want to see as a result is this :



      ATYPCODE AGLTCODE AGLTLVL ATYPCODE1 ATYPCODE2 ATYPCODE3 ATYPCODE4 ATYPDESC1 ATYPDESC2 ATYPDESC3 ATYPDESC4 


      and values for each column



      ATYPCODE = 1178 
      AGLTCODE = 3000 1911701178
      AGLTLVL = 4
      ATYPCODE1 = 3000
      ATYPCODE2 = 19
      ATYPCODE3 = 1170
      ATYPCODE4 = 1178
      ATYPDESC1 = A
      ATYPDESC2 = B
      ATYPDESC3 = C
      ATYPDESC4 = D


      and also the next record is



      ATYPCODE = 2020 
      AGLTCODE = 4000 182020
      AGLTLVL = 3
      ATYPCODE1 = 4000
      ATYPCODE2 = 18
      ATYPCODE3 = 2020
      ATYPCODE4 = 2020(last value is repeated)
      ATYPDESC1 = AA
      ATYPDESC2 = BB
      ATYPDESC3 = CC
      ATYPDESC4 = CC(Last Values is repeated)


      as you can see some records have 4 levels and some have 3 levels
      since the structure of the destination table is fixed,for those with 3 levels , last value ATYPCODE3 and ATYPDESC3should be repeated for columns ATYPCODE4 and ATYPDESC4 .



      the only part of query I was able to write was this cause we only nees to store the last level and nothing comes to mind for the rest of the query



      SELECT b.ATYPCODE , b.AGLTCODE , b.AGLTLVL
      FROM ACCOUNT1 a inner join
      ACCOUNT2 b on a.ATYPCODE = b.ATYPCODE
      where a.ATLASTFLAG = 1









      share|improve this question
















      I'm struggling with a very difficult and complicated query here and I need your help.



      I have two tables as you can see below:



      1) ACCOUNT1:(ATYPCODE int, ATYPDESC varchar(50), ATLASTFLAG varchar(50))


      some example data of this table are:



      ATYPCODE ATYPDESC ATLASTFLAG 
      3000 A 0
      19 B 0
      1170 C 0
      1178 D 1
      4000 AA 0
      18 BB 0
      2020 CC 1


      Column ATLASTFLAG shows whether this record is the last level .
      Table number two is



      2) ACCOUNT2:(ATYPCODE int, AGLTCODE varchar(50), AGLTLVL int)


      some example data of this table are:



       ATYPCODE AGLTCODE AGLTLVL 
      3000 3000 1
      19 3000 19 2
      1170 3000 191170 3
      1178 3000 1911701178 4
      4000 4000 1
      18 4000 18 2
      2020 4000 182020 3


      Column ATYPCODE is exactly the same as ATYPCODE column in the first table.Column AGLTCODE is bult based on the concatenation of ATYPCODEcolumn as you can see. The point is that the second level added to the first level with two spaces . so we have 3000+space+space+19+Other_levels and we have to separate this column exactly with 4 characters.
      and the column AGLTLVL shows the level of each ATYPCODE .



      what we want to see as a result is this :



      ATYPCODE AGLTCODE AGLTLVL ATYPCODE1 ATYPCODE2 ATYPCODE3 ATYPCODE4 ATYPDESC1 ATYPDESC2 ATYPDESC3 ATYPDESC4 


      and values for each column



      ATYPCODE = 1178 
      AGLTCODE = 3000 1911701178
      AGLTLVL = 4
      ATYPCODE1 = 3000
      ATYPCODE2 = 19
      ATYPCODE3 = 1170
      ATYPCODE4 = 1178
      ATYPDESC1 = A
      ATYPDESC2 = B
      ATYPDESC3 = C
      ATYPDESC4 = D


      and also the next record is



      ATYPCODE = 2020 
      AGLTCODE = 4000 182020
      AGLTLVL = 3
      ATYPCODE1 = 4000
      ATYPCODE2 = 18
      ATYPCODE3 = 2020
      ATYPCODE4 = 2020(last value is repeated)
      ATYPDESC1 = AA
      ATYPDESC2 = BB
      ATYPDESC3 = CC
      ATYPDESC4 = CC(Last Values is repeated)


      as you can see some records have 4 levels and some have 3 levels
      since the structure of the destination table is fixed,for those with 3 levels , last value ATYPCODE3 and ATYPDESC3should be repeated for columns ATYPCODE4 and ATYPDESC4 .



      the only part of query I was able to write was this cause we only nees to store the last level and nothing comes to mind for the rest of the query



      SELECT b.ATYPCODE , b.AGLTCODE , b.AGLTLVL
      FROM ACCOUNT1 a inner join
      ACCOUNT2 b on a.ATYPCODE = b.ATYPCODE
      where a.ATLASTFLAG = 1






      sql-server sql-server-2014 query






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 9 hours ago









      Paul White

      57.4k15 gold badges302 silver badges475 bronze badges




      57.4k15 gold badges302 silver badges475 bronze badges










      asked 11 hours ago









      Pantea TourangPantea Tourang

      47914 bronze badges




      47914 bronze badges




















          1 Answer
          1






          active

          oldest

          votes


















          3














          The first thing I would do is create some keys on the source tables:



          CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT1 (ATYPCODE);
          CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT2 (AGLTLVL, AGLTCODE);


          Then organize the data into a useful hierarchy using a recursive query to assign group and row numbers within the structure:



          CREATE TABLE #Data
          (
          grp integer NOT NULL,
          rn integer NOT NULL,
          ATYPCODE integer NOT NULL,
          AGLTLVL integer NOT NULL,
          AGLTCODE varchar(50) NOT NULL,

          PRIMARY KEY (grp, rn DESC)
          );

          WITH R AS
          (
          -- Anchor: rows where AGLTLVL = 1
          SELECT
          grp = ROW_NUMBER() OVER (ORDER BY A.AGLTCODE),
          rn = 1,
          A.ATYPCODE,
          A.AGLTLVL,
          AGLTCODE = CONVERT(varchar(50), A.AGLTCODE + SPACE(2))
          FROM dbo.ACCOUNT2 AS A
          WHERE
          A.AGLTLVL = 1

          UNION ALL

          -- Recursive: find the next AGLTLVL row in sequence
          SELECT
          R.grp,
          R.rn + 1,
          A.ATYPCODE,
          A.AGLTLVL,
          A.AGLTCODE
          FROM R
          JOIN dbo.ACCOUNT2 AS A WITH (FORCESEEK)
          ON A.AGLTLVL = R.AGLTLVL + 1
          AND A.AGLTCODE LIKE R.AGLTCODE + '%'
          AND A.AGLTCODE = R.AGLTCODE + CONVERT(varchar(11), A.ATYPCODE)
          )
          INSERT #Data
          (
          grp,
          rn,
          ATYPCODE,
          AGLTLVL,
          AGLTCODE
          )
          SELECT
          R.grp,
          R.rn,
          R.ATYPCODE,
          R.AGLTLVL,
          R.AGLTCODE
          FROM R
          OPTION (MAXRECURSION 0);


          The contents of the #Data table at this point are:



          ╔═════╦════╦══════════╦═════════╦══════════════════╗
          ║ grp ║ rn ║ ATYPCODE ║ AGLTLVL ║ AGLTCODE ║
          ╠═════╬════╬══════════╬═════════╬══════════════════╣
          ║ 1 ║ 1 ║ 3000 ║ 1 ║ 3000 ║
          ║ 1 ║ 2 ║ 19 ║ 2 ║ 3000 19 ║
          ║ 1 ║ 3 ║ 1170 ║ 3 ║ 3000 191170 ║
          ║ 1 ║ 4 ║ 1178 ║ 4 ║ 3000 1911701178 ║
          ║ 2 ║ 1 ║ 4000 ║ 1 ║ 4000 ║
          ║ 2 ║ 2 ║ 18 ║ 2 ║ 4000 18 ║
          ║ 2 ║ 3 ║ 2020 ║ 3 ║ 4000 182020 ║
          ╚═════╩════╩══════════╩═════════╩══════════════════╝


          Then the final query becomes much easier. We take the values from the highest row number per group for some values, and pivot the others, while adding in the type descriptions from the other table:



          SELECT
          SQ2.ATYPCODE,
          SQ2.AGLTCODE,
          SQ2.AGLTLVL,
          SQ2.ATYPCODE1,
          -- Fill in any missing type codes
          ATYPCODE2 = COALESCE(SQ2.ATYPCODE2, SQ2.ATYPCODE1),
          ATYPCODE3 = COALESCE(SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
          ATYPCODE4 = COALESCE(SQ2.ATYPCODE4, SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
          -- Fill in any missing type descriptions
          ATYPDESC2 = COALESCE(SQ2.ATYPDESC2, SQ2.ATYPDESC1),
          ATYPDESC3 = COALESCE(SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1),
          ATYPDESC4 = COALESCE(SQ2.ATYPDESC4, SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1)
          FROM
          (
          SELECT
          -- Same in every row anyway
          ATYPCODE = MAX(SQ1.ATYPCODE),
          AGLTCODE = MAX(SQ1.AGLTCODE),
          AGLTLVL = MAX(SQ1.AGLTLVL),
          -- Pivot type codes
          ATYPCODE1 = MAX(IIF(SQ1.rn = 1, SQ1.TypeCode, NULL)),
          ATYPCODE2 = MAX(IIF(SQ1.rn = 2, SQ1.TypeCode, NULL)),
          ATYPCODE3 = MAX(IIF(SQ1.rn = 3, SQ1.TypeCode, NULL)),
          ATYPCODE4 = MAX(IIF(SQ1.rn = 4, SQ1.TypeCode, NULL)),
          -- Pivot type descriptions
          ATYPDESC1 = MAX(IIF(SQ1.rn = 1, SQ1.ATYPDESC, NULL)),
          ATYPDESC2 = MAX(IIF(SQ1.rn = 2, SQ1.ATYPDESC, NULL)),
          ATYPDESC3 = MAX(IIF(SQ1.rn = 3, SQ1.ATYPDESC, NULL)),
          ATYPDESC4 = MAX(IIF(SQ1.rn = 4, SQ1.ATYPDESC, NULL))
          FROM
          (
          SELECT
          -- Values taken from highest row number per group
          ATYPCODE = FIRST_VALUE(D.ATYPCODE) OVER (
          PARTITION BY D.grp
          ORDER BY D.rn DESC
          ROWS UNBOUNDED PRECEDING),
          AGLTCODE = FIRST_VALUE(D.AGLTCODE) OVER (
          PARTITION BY D.grp
          ORDER BY D.rn DESC
          ROWS UNBOUNDED PRECEDING),
          AGLTLVL = FIRST_VALUE(D.AGLTLVL) OVER (
          PARTITION BY D.grp
          ORDER BY D.rn DESC
          ROWS UNBOUNDED PRECEDING),
          -- Pivot data
          TypeCode = D.ATYPCODE,
          A.ATYPDESC,
          -- Groups and row numbers
          D.grp,
          D.rn
          FROM #Data AS D
          JOIN dbo.ACCOUNT1 AS A
          ON A.ATYPCODE = D.ATYPCODE
          ) AS SQ1
          GROUP BY
          SQ1.grp
          ) AS SQ2;


          db<>fiddle demo



          execution plan



          ╔══════════╦══════════════════╦═════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╗
          ║ ATYPCODE ║ AGLTCODE ║ AGLTLVL ║ ATYPCODE1 ║ ATYPCODE2 ║ ATYPCODE3 ║ ATYPCODE4 ║ ATYPDESC2 ║ ATYPDESC3 ║ ATYPDESC4 ║
          ╠══════════╬══════════════════╬═════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╣
          ║ 1178 ║ 3000 1911701178 ║ 4 ║ 3000 ║ 19 ║ 1170 ║ 1178 ║ B ║ C ║ D ║
          ║ 2020 ║ 4000 182020 ║ 3 ║ 4000 ║ 18 ║ 2020 ║ 2020 ║ BB ║ CC ║ CC ║
          ╚══════════╩══════════════════╩═════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╝





          share|improve this answer



























            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "182"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f242254%2fseparate-a-column-into-its-components-based-on-another-table%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            3














            The first thing I would do is create some keys on the source tables:



            CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT1 (ATYPCODE);
            CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT2 (AGLTLVL, AGLTCODE);


            Then organize the data into a useful hierarchy using a recursive query to assign group and row numbers within the structure:



            CREATE TABLE #Data
            (
            grp integer NOT NULL,
            rn integer NOT NULL,
            ATYPCODE integer NOT NULL,
            AGLTLVL integer NOT NULL,
            AGLTCODE varchar(50) NOT NULL,

            PRIMARY KEY (grp, rn DESC)
            );

            WITH R AS
            (
            -- Anchor: rows where AGLTLVL = 1
            SELECT
            grp = ROW_NUMBER() OVER (ORDER BY A.AGLTCODE),
            rn = 1,
            A.ATYPCODE,
            A.AGLTLVL,
            AGLTCODE = CONVERT(varchar(50), A.AGLTCODE + SPACE(2))
            FROM dbo.ACCOUNT2 AS A
            WHERE
            A.AGLTLVL = 1

            UNION ALL

            -- Recursive: find the next AGLTLVL row in sequence
            SELECT
            R.grp,
            R.rn + 1,
            A.ATYPCODE,
            A.AGLTLVL,
            A.AGLTCODE
            FROM R
            JOIN dbo.ACCOUNT2 AS A WITH (FORCESEEK)
            ON A.AGLTLVL = R.AGLTLVL + 1
            AND A.AGLTCODE LIKE R.AGLTCODE + '%'
            AND A.AGLTCODE = R.AGLTCODE + CONVERT(varchar(11), A.ATYPCODE)
            )
            INSERT #Data
            (
            grp,
            rn,
            ATYPCODE,
            AGLTLVL,
            AGLTCODE
            )
            SELECT
            R.grp,
            R.rn,
            R.ATYPCODE,
            R.AGLTLVL,
            R.AGLTCODE
            FROM R
            OPTION (MAXRECURSION 0);


            The contents of the #Data table at this point are:



            ╔═════╦════╦══════════╦═════════╦══════════════════╗
            ║ grp ║ rn ║ ATYPCODE ║ AGLTLVL ║ AGLTCODE ║
            ╠═════╬════╬══════════╬═════════╬══════════════════╣
            ║ 1 ║ 1 ║ 3000 ║ 1 ║ 3000 ║
            ║ 1 ║ 2 ║ 19 ║ 2 ║ 3000 19 ║
            ║ 1 ║ 3 ║ 1170 ║ 3 ║ 3000 191170 ║
            ║ 1 ║ 4 ║ 1178 ║ 4 ║ 3000 1911701178 ║
            ║ 2 ║ 1 ║ 4000 ║ 1 ║ 4000 ║
            ║ 2 ║ 2 ║ 18 ║ 2 ║ 4000 18 ║
            ║ 2 ║ 3 ║ 2020 ║ 3 ║ 4000 182020 ║
            ╚═════╩════╩══════════╩═════════╩══════════════════╝


            Then the final query becomes much easier. We take the values from the highest row number per group for some values, and pivot the others, while adding in the type descriptions from the other table:



            SELECT
            SQ2.ATYPCODE,
            SQ2.AGLTCODE,
            SQ2.AGLTLVL,
            SQ2.ATYPCODE1,
            -- Fill in any missing type codes
            ATYPCODE2 = COALESCE(SQ2.ATYPCODE2, SQ2.ATYPCODE1),
            ATYPCODE3 = COALESCE(SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
            ATYPCODE4 = COALESCE(SQ2.ATYPCODE4, SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
            -- Fill in any missing type descriptions
            ATYPDESC2 = COALESCE(SQ2.ATYPDESC2, SQ2.ATYPDESC1),
            ATYPDESC3 = COALESCE(SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1),
            ATYPDESC4 = COALESCE(SQ2.ATYPDESC4, SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1)
            FROM
            (
            SELECT
            -- Same in every row anyway
            ATYPCODE = MAX(SQ1.ATYPCODE),
            AGLTCODE = MAX(SQ1.AGLTCODE),
            AGLTLVL = MAX(SQ1.AGLTLVL),
            -- Pivot type codes
            ATYPCODE1 = MAX(IIF(SQ1.rn = 1, SQ1.TypeCode, NULL)),
            ATYPCODE2 = MAX(IIF(SQ1.rn = 2, SQ1.TypeCode, NULL)),
            ATYPCODE3 = MAX(IIF(SQ1.rn = 3, SQ1.TypeCode, NULL)),
            ATYPCODE4 = MAX(IIF(SQ1.rn = 4, SQ1.TypeCode, NULL)),
            -- Pivot type descriptions
            ATYPDESC1 = MAX(IIF(SQ1.rn = 1, SQ1.ATYPDESC, NULL)),
            ATYPDESC2 = MAX(IIF(SQ1.rn = 2, SQ1.ATYPDESC, NULL)),
            ATYPDESC3 = MAX(IIF(SQ1.rn = 3, SQ1.ATYPDESC, NULL)),
            ATYPDESC4 = MAX(IIF(SQ1.rn = 4, SQ1.ATYPDESC, NULL))
            FROM
            (
            SELECT
            -- Values taken from highest row number per group
            ATYPCODE = FIRST_VALUE(D.ATYPCODE) OVER (
            PARTITION BY D.grp
            ORDER BY D.rn DESC
            ROWS UNBOUNDED PRECEDING),
            AGLTCODE = FIRST_VALUE(D.AGLTCODE) OVER (
            PARTITION BY D.grp
            ORDER BY D.rn DESC
            ROWS UNBOUNDED PRECEDING),
            AGLTLVL = FIRST_VALUE(D.AGLTLVL) OVER (
            PARTITION BY D.grp
            ORDER BY D.rn DESC
            ROWS UNBOUNDED PRECEDING),
            -- Pivot data
            TypeCode = D.ATYPCODE,
            A.ATYPDESC,
            -- Groups and row numbers
            D.grp,
            D.rn
            FROM #Data AS D
            JOIN dbo.ACCOUNT1 AS A
            ON A.ATYPCODE = D.ATYPCODE
            ) AS SQ1
            GROUP BY
            SQ1.grp
            ) AS SQ2;


            db<>fiddle demo



            execution plan



            ╔══════════╦══════════════════╦═════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╗
            ║ ATYPCODE ║ AGLTCODE ║ AGLTLVL ║ ATYPCODE1 ║ ATYPCODE2 ║ ATYPCODE3 ║ ATYPCODE4 ║ ATYPDESC2 ║ ATYPDESC3 ║ ATYPDESC4 ║
            ╠══════════╬══════════════════╬═════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╣
            ║ 1178 ║ 3000 1911701178 ║ 4 ║ 3000 ║ 19 ║ 1170 ║ 1178 ║ B ║ C ║ D ║
            ║ 2020 ║ 4000 182020 ║ 3 ║ 4000 ║ 18 ║ 2020 ║ 2020 ║ BB ║ CC ║ CC ║
            ╚══════════╩══════════════════╩═════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╝





            share|improve this answer





























              3














              The first thing I would do is create some keys on the source tables:



              CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT1 (ATYPCODE);
              CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT2 (AGLTLVL, AGLTCODE);


              Then organize the data into a useful hierarchy using a recursive query to assign group and row numbers within the structure:



              CREATE TABLE #Data
              (
              grp integer NOT NULL,
              rn integer NOT NULL,
              ATYPCODE integer NOT NULL,
              AGLTLVL integer NOT NULL,
              AGLTCODE varchar(50) NOT NULL,

              PRIMARY KEY (grp, rn DESC)
              );

              WITH R AS
              (
              -- Anchor: rows where AGLTLVL = 1
              SELECT
              grp = ROW_NUMBER() OVER (ORDER BY A.AGLTCODE),
              rn = 1,
              A.ATYPCODE,
              A.AGLTLVL,
              AGLTCODE = CONVERT(varchar(50), A.AGLTCODE + SPACE(2))
              FROM dbo.ACCOUNT2 AS A
              WHERE
              A.AGLTLVL = 1

              UNION ALL

              -- Recursive: find the next AGLTLVL row in sequence
              SELECT
              R.grp,
              R.rn + 1,
              A.ATYPCODE,
              A.AGLTLVL,
              A.AGLTCODE
              FROM R
              JOIN dbo.ACCOUNT2 AS A WITH (FORCESEEK)
              ON A.AGLTLVL = R.AGLTLVL + 1
              AND A.AGLTCODE LIKE R.AGLTCODE + '%'
              AND A.AGLTCODE = R.AGLTCODE + CONVERT(varchar(11), A.ATYPCODE)
              )
              INSERT #Data
              (
              grp,
              rn,
              ATYPCODE,
              AGLTLVL,
              AGLTCODE
              )
              SELECT
              R.grp,
              R.rn,
              R.ATYPCODE,
              R.AGLTLVL,
              R.AGLTCODE
              FROM R
              OPTION (MAXRECURSION 0);


              The contents of the #Data table at this point are:



              ╔═════╦════╦══════════╦═════════╦══════════════════╗
              ║ grp ║ rn ║ ATYPCODE ║ AGLTLVL ║ AGLTCODE ║
              ╠═════╬════╬══════════╬═════════╬══════════════════╣
              ║ 1 ║ 1 ║ 3000 ║ 1 ║ 3000 ║
              ║ 1 ║ 2 ║ 19 ║ 2 ║ 3000 19 ║
              ║ 1 ║ 3 ║ 1170 ║ 3 ║ 3000 191170 ║
              ║ 1 ║ 4 ║ 1178 ║ 4 ║ 3000 1911701178 ║
              ║ 2 ║ 1 ║ 4000 ║ 1 ║ 4000 ║
              ║ 2 ║ 2 ║ 18 ║ 2 ║ 4000 18 ║
              ║ 2 ║ 3 ║ 2020 ║ 3 ║ 4000 182020 ║
              ╚═════╩════╩══════════╩═════════╩══════════════════╝


              Then the final query becomes much easier. We take the values from the highest row number per group for some values, and pivot the others, while adding in the type descriptions from the other table:



              SELECT
              SQ2.ATYPCODE,
              SQ2.AGLTCODE,
              SQ2.AGLTLVL,
              SQ2.ATYPCODE1,
              -- Fill in any missing type codes
              ATYPCODE2 = COALESCE(SQ2.ATYPCODE2, SQ2.ATYPCODE1),
              ATYPCODE3 = COALESCE(SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
              ATYPCODE4 = COALESCE(SQ2.ATYPCODE4, SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
              -- Fill in any missing type descriptions
              ATYPDESC2 = COALESCE(SQ2.ATYPDESC2, SQ2.ATYPDESC1),
              ATYPDESC3 = COALESCE(SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1),
              ATYPDESC4 = COALESCE(SQ2.ATYPDESC4, SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1)
              FROM
              (
              SELECT
              -- Same in every row anyway
              ATYPCODE = MAX(SQ1.ATYPCODE),
              AGLTCODE = MAX(SQ1.AGLTCODE),
              AGLTLVL = MAX(SQ1.AGLTLVL),
              -- Pivot type codes
              ATYPCODE1 = MAX(IIF(SQ1.rn = 1, SQ1.TypeCode, NULL)),
              ATYPCODE2 = MAX(IIF(SQ1.rn = 2, SQ1.TypeCode, NULL)),
              ATYPCODE3 = MAX(IIF(SQ1.rn = 3, SQ1.TypeCode, NULL)),
              ATYPCODE4 = MAX(IIF(SQ1.rn = 4, SQ1.TypeCode, NULL)),
              -- Pivot type descriptions
              ATYPDESC1 = MAX(IIF(SQ1.rn = 1, SQ1.ATYPDESC, NULL)),
              ATYPDESC2 = MAX(IIF(SQ1.rn = 2, SQ1.ATYPDESC, NULL)),
              ATYPDESC3 = MAX(IIF(SQ1.rn = 3, SQ1.ATYPDESC, NULL)),
              ATYPDESC4 = MAX(IIF(SQ1.rn = 4, SQ1.ATYPDESC, NULL))
              FROM
              (
              SELECT
              -- Values taken from highest row number per group
              ATYPCODE = FIRST_VALUE(D.ATYPCODE) OVER (
              PARTITION BY D.grp
              ORDER BY D.rn DESC
              ROWS UNBOUNDED PRECEDING),
              AGLTCODE = FIRST_VALUE(D.AGLTCODE) OVER (
              PARTITION BY D.grp
              ORDER BY D.rn DESC
              ROWS UNBOUNDED PRECEDING),
              AGLTLVL = FIRST_VALUE(D.AGLTLVL) OVER (
              PARTITION BY D.grp
              ORDER BY D.rn DESC
              ROWS UNBOUNDED PRECEDING),
              -- Pivot data
              TypeCode = D.ATYPCODE,
              A.ATYPDESC,
              -- Groups and row numbers
              D.grp,
              D.rn
              FROM #Data AS D
              JOIN dbo.ACCOUNT1 AS A
              ON A.ATYPCODE = D.ATYPCODE
              ) AS SQ1
              GROUP BY
              SQ1.grp
              ) AS SQ2;


              db<>fiddle demo



              execution plan



              ╔══════════╦══════════════════╦═════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╗
              ║ ATYPCODE ║ AGLTCODE ║ AGLTLVL ║ ATYPCODE1 ║ ATYPCODE2 ║ ATYPCODE3 ║ ATYPCODE4 ║ ATYPDESC2 ║ ATYPDESC3 ║ ATYPDESC4 ║
              ╠══════════╬══════════════════╬═════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╣
              ║ 1178 ║ 3000 1911701178 ║ 4 ║ 3000 ║ 19 ║ 1170 ║ 1178 ║ B ║ C ║ D ║
              ║ 2020 ║ 4000 182020 ║ 3 ║ 4000 ║ 18 ║ 2020 ║ 2020 ║ BB ║ CC ║ CC ║
              ╚══════════╩══════════════════╩═════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╝





              share|improve this answer



























                3












                3








                3







                The first thing I would do is create some keys on the source tables:



                CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT1 (ATYPCODE);
                CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT2 (AGLTLVL, AGLTCODE);


                Then organize the data into a useful hierarchy using a recursive query to assign group and row numbers within the structure:



                CREATE TABLE #Data
                (
                grp integer NOT NULL,
                rn integer NOT NULL,
                ATYPCODE integer NOT NULL,
                AGLTLVL integer NOT NULL,
                AGLTCODE varchar(50) NOT NULL,

                PRIMARY KEY (grp, rn DESC)
                );

                WITH R AS
                (
                -- Anchor: rows where AGLTLVL = 1
                SELECT
                grp = ROW_NUMBER() OVER (ORDER BY A.AGLTCODE),
                rn = 1,
                A.ATYPCODE,
                A.AGLTLVL,
                AGLTCODE = CONVERT(varchar(50), A.AGLTCODE + SPACE(2))
                FROM dbo.ACCOUNT2 AS A
                WHERE
                A.AGLTLVL = 1

                UNION ALL

                -- Recursive: find the next AGLTLVL row in sequence
                SELECT
                R.grp,
                R.rn + 1,
                A.ATYPCODE,
                A.AGLTLVL,
                A.AGLTCODE
                FROM R
                JOIN dbo.ACCOUNT2 AS A WITH (FORCESEEK)
                ON A.AGLTLVL = R.AGLTLVL + 1
                AND A.AGLTCODE LIKE R.AGLTCODE + '%'
                AND A.AGLTCODE = R.AGLTCODE + CONVERT(varchar(11), A.ATYPCODE)
                )
                INSERT #Data
                (
                grp,
                rn,
                ATYPCODE,
                AGLTLVL,
                AGLTCODE
                )
                SELECT
                R.grp,
                R.rn,
                R.ATYPCODE,
                R.AGLTLVL,
                R.AGLTCODE
                FROM R
                OPTION (MAXRECURSION 0);


                The contents of the #Data table at this point are:



                ╔═════╦════╦══════════╦═════════╦══════════════════╗
                ║ grp ║ rn ║ ATYPCODE ║ AGLTLVL ║ AGLTCODE ║
                ╠═════╬════╬══════════╬═════════╬══════════════════╣
                ║ 1 ║ 1 ║ 3000 ║ 1 ║ 3000 ║
                ║ 1 ║ 2 ║ 19 ║ 2 ║ 3000 19 ║
                ║ 1 ║ 3 ║ 1170 ║ 3 ║ 3000 191170 ║
                ║ 1 ║ 4 ║ 1178 ║ 4 ║ 3000 1911701178 ║
                ║ 2 ║ 1 ║ 4000 ║ 1 ║ 4000 ║
                ║ 2 ║ 2 ║ 18 ║ 2 ║ 4000 18 ║
                ║ 2 ║ 3 ║ 2020 ║ 3 ║ 4000 182020 ║
                ╚═════╩════╩══════════╩═════════╩══════════════════╝


                Then the final query becomes much easier. We take the values from the highest row number per group for some values, and pivot the others, while adding in the type descriptions from the other table:



                SELECT
                SQ2.ATYPCODE,
                SQ2.AGLTCODE,
                SQ2.AGLTLVL,
                SQ2.ATYPCODE1,
                -- Fill in any missing type codes
                ATYPCODE2 = COALESCE(SQ2.ATYPCODE2, SQ2.ATYPCODE1),
                ATYPCODE3 = COALESCE(SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
                ATYPCODE4 = COALESCE(SQ2.ATYPCODE4, SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
                -- Fill in any missing type descriptions
                ATYPDESC2 = COALESCE(SQ2.ATYPDESC2, SQ2.ATYPDESC1),
                ATYPDESC3 = COALESCE(SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1),
                ATYPDESC4 = COALESCE(SQ2.ATYPDESC4, SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1)
                FROM
                (
                SELECT
                -- Same in every row anyway
                ATYPCODE = MAX(SQ1.ATYPCODE),
                AGLTCODE = MAX(SQ1.AGLTCODE),
                AGLTLVL = MAX(SQ1.AGLTLVL),
                -- Pivot type codes
                ATYPCODE1 = MAX(IIF(SQ1.rn = 1, SQ1.TypeCode, NULL)),
                ATYPCODE2 = MAX(IIF(SQ1.rn = 2, SQ1.TypeCode, NULL)),
                ATYPCODE3 = MAX(IIF(SQ1.rn = 3, SQ1.TypeCode, NULL)),
                ATYPCODE4 = MAX(IIF(SQ1.rn = 4, SQ1.TypeCode, NULL)),
                -- Pivot type descriptions
                ATYPDESC1 = MAX(IIF(SQ1.rn = 1, SQ1.ATYPDESC, NULL)),
                ATYPDESC2 = MAX(IIF(SQ1.rn = 2, SQ1.ATYPDESC, NULL)),
                ATYPDESC3 = MAX(IIF(SQ1.rn = 3, SQ1.ATYPDESC, NULL)),
                ATYPDESC4 = MAX(IIF(SQ1.rn = 4, SQ1.ATYPDESC, NULL))
                FROM
                (
                SELECT
                -- Values taken from highest row number per group
                ATYPCODE = FIRST_VALUE(D.ATYPCODE) OVER (
                PARTITION BY D.grp
                ORDER BY D.rn DESC
                ROWS UNBOUNDED PRECEDING),
                AGLTCODE = FIRST_VALUE(D.AGLTCODE) OVER (
                PARTITION BY D.grp
                ORDER BY D.rn DESC
                ROWS UNBOUNDED PRECEDING),
                AGLTLVL = FIRST_VALUE(D.AGLTLVL) OVER (
                PARTITION BY D.grp
                ORDER BY D.rn DESC
                ROWS UNBOUNDED PRECEDING),
                -- Pivot data
                TypeCode = D.ATYPCODE,
                A.ATYPDESC,
                -- Groups and row numbers
                D.grp,
                D.rn
                FROM #Data AS D
                JOIN dbo.ACCOUNT1 AS A
                ON A.ATYPCODE = D.ATYPCODE
                ) AS SQ1
                GROUP BY
                SQ1.grp
                ) AS SQ2;


                db<>fiddle demo



                execution plan



                ╔══════════╦══════════════════╦═════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╗
                ║ ATYPCODE ║ AGLTCODE ║ AGLTLVL ║ ATYPCODE1 ║ ATYPCODE2 ║ ATYPCODE3 ║ ATYPCODE4 ║ ATYPDESC2 ║ ATYPDESC3 ║ ATYPDESC4 ║
                ╠══════════╬══════════════════╬═════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╣
                ║ 1178 ║ 3000 1911701178 ║ 4 ║ 3000 ║ 19 ║ 1170 ║ 1178 ║ B ║ C ║ D ║
                ║ 2020 ║ 4000 182020 ║ 3 ║ 4000 ║ 18 ║ 2020 ║ 2020 ║ BB ║ CC ║ CC ║
                ╚══════════╩══════════════════╩═════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╝





                share|improve this answer















                The first thing I would do is create some keys on the source tables:



                CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT1 (ATYPCODE);
                CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.ACCOUNT2 (AGLTLVL, AGLTCODE);


                Then organize the data into a useful hierarchy using a recursive query to assign group and row numbers within the structure:



                CREATE TABLE #Data
                (
                grp integer NOT NULL,
                rn integer NOT NULL,
                ATYPCODE integer NOT NULL,
                AGLTLVL integer NOT NULL,
                AGLTCODE varchar(50) NOT NULL,

                PRIMARY KEY (grp, rn DESC)
                );

                WITH R AS
                (
                -- Anchor: rows where AGLTLVL = 1
                SELECT
                grp = ROW_NUMBER() OVER (ORDER BY A.AGLTCODE),
                rn = 1,
                A.ATYPCODE,
                A.AGLTLVL,
                AGLTCODE = CONVERT(varchar(50), A.AGLTCODE + SPACE(2))
                FROM dbo.ACCOUNT2 AS A
                WHERE
                A.AGLTLVL = 1

                UNION ALL

                -- Recursive: find the next AGLTLVL row in sequence
                SELECT
                R.grp,
                R.rn + 1,
                A.ATYPCODE,
                A.AGLTLVL,
                A.AGLTCODE
                FROM R
                JOIN dbo.ACCOUNT2 AS A WITH (FORCESEEK)
                ON A.AGLTLVL = R.AGLTLVL + 1
                AND A.AGLTCODE LIKE R.AGLTCODE + '%'
                AND A.AGLTCODE = R.AGLTCODE + CONVERT(varchar(11), A.ATYPCODE)
                )
                INSERT #Data
                (
                grp,
                rn,
                ATYPCODE,
                AGLTLVL,
                AGLTCODE
                )
                SELECT
                R.grp,
                R.rn,
                R.ATYPCODE,
                R.AGLTLVL,
                R.AGLTCODE
                FROM R
                OPTION (MAXRECURSION 0);


                The contents of the #Data table at this point are:



                ╔═════╦════╦══════════╦═════════╦══════════════════╗
                ║ grp ║ rn ║ ATYPCODE ║ AGLTLVL ║ AGLTCODE ║
                ╠═════╬════╬══════════╬═════════╬══════════════════╣
                ║ 1 ║ 1 ║ 3000 ║ 1 ║ 3000 ║
                ║ 1 ║ 2 ║ 19 ║ 2 ║ 3000 19 ║
                ║ 1 ║ 3 ║ 1170 ║ 3 ║ 3000 191170 ║
                ║ 1 ║ 4 ║ 1178 ║ 4 ║ 3000 1911701178 ║
                ║ 2 ║ 1 ║ 4000 ║ 1 ║ 4000 ║
                ║ 2 ║ 2 ║ 18 ║ 2 ║ 4000 18 ║
                ║ 2 ║ 3 ║ 2020 ║ 3 ║ 4000 182020 ║
                ╚═════╩════╩══════════╩═════════╩══════════════════╝


                Then the final query becomes much easier. We take the values from the highest row number per group for some values, and pivot the others, while adding in the type descriptions from the other table:



                SELECT
                SQ2.ATYPCODE,
                SQ2.AGLTCODE,
                SQ2.AGLTLVL,
                SQ2.ATYPCODE1,
                -- Fill in any missing type codes
                ATYPCODE2 = COALESCE(SQ2.ATYPCODE2, SQ2.ATYPCODE1),
                ATYPCODE3 = COALESCE(SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
                ATYPCODE4 = COALESCE(SQ2.ATYPCODE4, SQ2.ATYPCODE3, SQ2.ATYPCODE2, SQ2.ATYPCODE1),
                -- Fill in any missing type descriptions
                ATYPDESC2 = COALESCE(SQ2.ATYPDESC2, SQ2.ATYPDESC1),
                ATYPDESC3 = COALESCE(SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1),
                ATYPDESC4 = COALESCE(SQ2.ATYPDESC4, SQ2.ATYPDESC3, SQ2.ATYPDESC2, SQ2.ATYPDESC1)
                FROM
                (
                SELECT
                -- Same in every row anyway
                ATYPCODE = MAX(SQ1.ATYPCODE),
                AGLTCODE = MAX(SQ1.AGLTCODE),
                AGLTLVL = MAX(SQ1.AGLTLVL),
                -- Pivot type codes
                ATYPCODE1 = MAX(IIF(SQ1.rn = 1, SQ1.TypeCode, NULL)),
                ATYPCODE2 = MAX(IIF(SQ1.rn = 2, SQ1.TypeCode, NULL)),
                ATYPCODE3 = MAX(IIF(SQ1.rn = 3, SQ1.TypeCode, NULL)),
                ATYPCODE4 = MAX(IIF(SQ1.rn = 4, SQ1.TypeCode, NULL)),
                -- Pivot type descriptions
                ATYPDESC1 = MAX(IIF(SQ1.rn = 1, SQ1.ATYPDESC, NULL)),
                ATYPDESC2 = MAX(IIF(SQ1.rn = 2, SQ1.ATYPDESC, NULL)),
                ATYPDESC3 = MAX(IIF(SQ1.rn = 3, SQ1.ATYPDESC, NULL)),
                ATYPDESC4 = MAX(IIF(SQ1.rn = 4, SQ1.ATYPDESC, NULL))
                FROM
                (
                SELECT
                -- Values taken from highest row number per group
                ATYPCODE = FIRST_VALUE(D.ATYPCODE) OVER (
                PARTITION BY D.grp
                ORDER BY D.rn DESC
                ROWS UNBOUNDED PRECEDING),
                AGLTCODE = FIRST_VALUE(D.AGLTCODE) OVER (
                PARTITION BY D.grp
                ORDER BY D.rn DESC
                ROWS UNBOUNDED PRECEDING),
                AGLTLVL = FIRST_VALUE(D.AGLTLVL) OVER (
                PARTITION BY D.grp
                ORDER BY D.rn DESC
                ROWS UNBOUNDED PRECEDING),
                -- Pivot data
                TypeCode = D.ATYPCODE,
                A.ATYPDESC,
                -- Groups and row numbers
                D.grp,
                D.rn
                FROM #Data AS D
                JOIN dbo.ACCOUNT1 AS A
                ON A.ATYPCODE = D.ATYPCODE
                ) AS SQ1
                GROUP BY
                SQ1.grp
                ) AS SQ2;


                db<>fiddle demo



                execution plan



                ╔══════════╦══════════════════╦═════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╗
                ║ ATYPCODE ║ AGLTCODE ║ AGLTLVL ║ ATYPCODE1 ║ ATYPCODE2 ║ ATYPCODE3 ║ ATYPCODE4 ║ ATYPDESC2 ║ ATYPDESC3 ║ ATYPDESC4 ║
                ╠══════════╬══════════════════╬═════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╬═══════════╣
                ║ 1178 ║ 3000 1911701178 ║ 4 ║ 3000 ║ 19 ║ 1170 ║ 1178 ║ B ║ C ║ D ║
                ║ 2020 ║ 4000 182020 ║ 3 ║ 4000 ║ 18 ║ 2020 ║ 2020 ║ BB ║ CC ║ CC ║
                ╚══════════╩══════════════════╩═════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╝






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 6 hours ago

























                answered 9 hours ago









                Paul WhitePaul White

                57.4k15 gold badges302 silver badges475 bronze badges




                57.4k15 gold badges302 silver badges475 bronze badges



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Database Administrators Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f242254%2fseparate-a-column-into-its-components-based-on-another-table%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    19. јануар Садржај Догађаји Рођења Смрти Празници и дани сећања Види још Референце Мени за навигацијуу

                    Israel Cuprins Etimologie | Istorie | Geografie | Politică | Demografie | Educație | Economie | Cultură | Note explicative | Note bibliografice | Bibliografie | Legături externe | Meniu de navigaresite web oficialfacebooktweeterGoogle+Instagramcanal YouTubeInstagramtextmodificaremodificarewww.technion.ac.ilnew.huji.ac.ilwww.weizmann.ac.ilwww1.biu.ac.ilenglish.tau.ac.ilwww.haifa.ac.ilin.bgu.ac.ilwww.openu.ac.ilwww.ariel.ac.ilCIA FactbookHarta Israelului"Negotiating Jerusalem," Palestine–Israel JournalThe Schizoid Nature of Modern Hebrew: A Slavic Language in Search of a Semitic Past„Arabic in Israel: an official language and a cultural bridge”„Latest Population Statistics for Israel”„Israel Population”„Tables”„Report for Selected Countries and Subjects”Human Development Report 2016: Human Development for Everyone„Distribution of family income - Gini index”The World FactbookJerusalem Law„Israel”„Israel”„Zionist Leaders: David Ben-Gurion 1886–1973”„The status of Jerusalem”„Analysis: Kadima's big plans”„Israel's Hard-Learned Lessons”„The Legacy of Undefined Borders, Tel Aviv Notes No. 40, 5 iunie 2002”„Israel Journal: A Land Without Borders”„Population”„Israel closes decade with population of 7.5 million”Time Series-DataBank„Selected Statistics on Jerusalem Day 2007 (Hebrew)”Golan belongs to Syria, Druze protestGlobal Survey 2006: Middle East Progress Amid Global Gains in FreedomWHO: Life expectancy in Israel among highest in the worldInternational Monetary Fund, World Economic Outlook Database, April 2011: Nominal GDP list of countries. Data for the year 2010.„Israel's accession to the OECD”Popular Opinion„On the Move”Hosea 12:5„Walking the Bible Timeline”„Palestine: History”„Return to Zion”An invention called 'the Jewish people' – Haaretz – Israel NewsoriginalJewish and Non-Jewish Population of Palestine-Israel (1517–2004)ImmigrationJewishvirtuallibrary.orgChapter One: The Heralders of Zionism„The birth of modern Israel: A scrap of paper that changed history”„League of Nations: The Mandate for Palestine, 24 iulie 1922”The Population of Palestine Prior to 1948originalBackground Paper No. 47 (ST/DPI/SER.A/47)History: Foreign DominationTwo Hundred and Seventh Plenary Meeting„Israel (Labor Zionism)”Population, by Religion and Population GroupThe Suez CrisisAdolf EichmannJustice Ministry Reply to Amnesty International Report„The Interregnum”Israel Ministry of Foreign Affairs – The Palestinian National Covenant- July 1968Research on terrorism: trends, achievements & failuresThe Routledge Atlas of the Arab–Israeli conflict: The Complete History of the Struggle and the Efforts to Resolve It"George Habash, Palestinian Terrorism Tactician, Dies at 82."„1973: Arab states attack Israeli forces”Agranat Commission„Has Israel Annexed East Jerusalem?”original„After 4 Years, Intifada Still Smolders”From the End of the Cold War to 2001originalThe Oslo Accords, 1993Israel-PLO Recognition – Exchange of Letters between PM Rabin and Chairman Arafat – Sept 9- 1993Foundation for Middle East PeaceSources of Population Growth: Total Israeli Population and Settler Population, 1991–2003original„Israel marks Rabin assassination”The Wye River Memorandumoriginal„West Bank barrier route disputed, Israeli missile kills 2”"Permanent Ceasefire to Be Based on Creation Of Buffer Zone Free of Armed Personnel Other than UN, Lebanese Forces"„Hezbollah kills 8 soldiers, kidnaps two in offensive on northern border”„Olmert confirms peace talks with Syria”„Battleground Gaza: Israeli ground forces invade the strip”„IDF begins Gaza troop withdrawal, hours after ending 3-week offensive”„THE LAND: Geography and Climate”„Area of districts, sub-districts, natural regions and lakes”„Israel - Geography”„Makhteshim Country”Israel and the Palestinian Territories„Makhtesh Ramon”„The Living Dead Sea”„Temperatures reach record high in Pakistan”„Climate Extremes In Israel”Israel in figures„Deuteronom”„JNF: 240 million trees planted since 1901”„Vegetation of Israel and Neighboring Countries”Environmental Law in Israel„Executive branch”„Israel's election process explained”„The Electoral System in Israel”„Constitution for Israel”„All 120 incoming Knesset members”„Statul ISRAEL”„The Judiciary: The Court System”„Israel's high court unique in region”„Israel and the International Criminal Court: A Legal Battlefield”„Localities and population, by population group, district, sub-district and natural region”„Israel: Districts, Major Cities, Urban Localities & Metropolitan Areas”„Israel-Egypt Relations: Background & Overview of Peace Treaty”„Solana to Haaretz: New Rules of War Needed for Age of Terror”„Israel's Announcement Regarding Settlements”„United Nations Security Council Resolution 497”„Security Council resolution 478 (1980) on the status of Jerusalem”„Arabs will ask U.N. to seek razing of Israeli wall”„Olmert: Willing to trade land for peace”„Mapping Peace between Syria and Israel”„Egypt: Israel must accept the land-for-peace formula”„Israel: Age structure from 2005 to 2015”„Global, regional, and national disability-adjusted life years (DALYs) for 306 diseases and injuries and healthy life expectancy (HALE) for 188 countries, 1990–2013: quantifying the epidemiological transition”10.1016/S0140-6736(15)61340-X„World Health Statistics 2014”„Life expectancy for Israeli men world's 4th highest”„Family Structure and Well-Being Across Israel's Diverse Population”„Fertility among Jewish and Muslim Women in Israel, by Level of Religiosity, 1979-2009”„Israel leaders in birth rate, but poverty major challenge”„Ethnic Groups”„Israel's population: Over 8.5 million”„Israel - Ethnic groups”„Jews, by country of origin and age”„Minority Communities in Israel: Background & Overview”„Israel”„Language in Israel”„Selected Data from the 2011 Social Survey on Mastery of the Hebrew Language and Usage of Languages”„Religions”„5 facts about Israeli Druze, a unique religious and ethnic group”„Israël”Israel Country Study Guide„Haredi city in Negev – blessing or curse?”„New town Harish harbors hopes of being more than another Pleasantville”„List of localities, in alphabetical order”„Muncitorii români, doriți în Israel”„Prietenia româno-israeliană la nevoie se cunoaște”„The Higher Education System in Israel”„Middle East”„Academic Ranking of World Universities 2016”„Israel”„Israel”„Jewish Nobel Prize Winners”„All Nobel Prizes in Literature”„All Nobel Peace Prizes”„All Prizes in Economic Sciences”„All Nobel Prizes in Chemistry”„List of Fields Medallists”„Sakharov Prize”„Țara care și-a sfidat "destinul" și se bate umăr la umăr cu Silicon Valley”„Apple's R&D center in Israel grew to about 800 employees”„Tim Cook: Apple's Herzliya R&D center second-largest in world”„Lecții de economie de la Israel”„Land use”Israel Investment and Business GuideA Country Study: IsraelCentral Bureau of StatisticsFlorin Diaconu, „Kadima: Flexibilitate și pragmatism, dar nici un compromis în chestiuni vitale", în Revista Institutului Diplomatic Român, anul I, numărul I, semestrul I, 2006, pp. 71-72Florin Diaconu, „Likud: Dreapta israeliană constant opusă retrocedării teritoriilor cureite prin luptă în 1967", în Revista Institutului Diplomatic Român, anul I, numărul I, semestrul I, 2006, pp. 73-74MassadaIsraelul a crescut in 50 de ani cât alte state intr-un mileniuIsrael Government PortalIsraelIsraelIsraelmmmmmXX451232cb118646298(data)4027808-634110000 0004 0372 0767n7900328503691455-bb46-37e3-91d2-cb064a35ffcc1003570400564274ge1294033523775214929302638955X146498911146498911

                    Кастелфранко ди Сопра Становништво Референце Спољашње везе Мени за навигацију43°37′18″ СГШ; 11°33′32″ ИГД / 43.62156° СГШ; 11.55885° ИГД / 43.62156; 11.5588543°37′18″ СГШ; 11°33′32″ ИГД / 43.62156° СГШ; 11.55885° ИГД / 43.62156; 11.558853179688„The GeoNames geographical database”„Istituto Nazionale di Statistica”проширитиууWorldCat156923403n850174324558639-1cb14643287r(подаци)