SQL Server Dynamic pivot by year month concatenated

kr98yfug  于 2023-05-28  发布在  其他
关注(0)|答案(1)|浏览(109)

I have the following data in a table. There will be many LocationID and for each location, there will be 120 months (fixed 10 years) of data.
| LOC | Yr | Mon | Amt |
| ------------ | ------------ | ------------ | ------------ |
| 101 | 2023 | 4 | 65.45 |
| 101 | 2023 | 5 | 65.45 |
| 101 | 2023 | 6 | 65.45 |
| 101 | 2023 | 7 | 65.45 |
| 101 | 2023 | 8 | 65.45 |
| 101 | 2023 | 9 | 65.45 |
| 101 | 2023 | 10 | 65.45 |
| 101 | 2023 | 11 | 65.45 |
| 101 | 2023 | 12 | 65.45 |
| 101 | 2024 | 1 | 65.45 |
| 101 | 2024 | 2 | 65.45 |
| 101 | 2024 | 3 | 65.45 |
| 101 | 2024 | 4 | 34.12 |
| 101 | 2024 | 5 | 34.12 |
| 101 | 2024 | 6 | 34.12 |

I'm trying to get it in a format like the following (ascending year-month order):

LOC2023-Apr2023-May2023-Jun2023-Jul2023-Aug2023-Sep2023-Oct2023-Nov2023-Dec2024-Jan.....
10165.4565.4565.4565.4565.4565.4565.4565.4565.4565.45

I got started with the following query to combine the date and month

SELECT 
    loc, CAST(yr AS varchar) + '-' + DATENAME(mm, DATEADD(mm, Mon, -1)) [Period], 
    Amt
FROM 
    TBL 
WHERE 
    loc = 101 AND plID = 11
ORDER BY
    Yr, Mon

Which returns this result:

locPeriodAmt
1012023-April65.45
1012023-August65.45
1012023-December65.45
1012023-July65.45

Needing some help figure out the best approach to get the data from this to the desired format/layout that I mentioned in the second table above..

Suggestions?

l7wslrjt

l7wslrjt1#

I came up with the following query which works. I had to put the data in a temp table as the CTE was not available in the second select (@query)! Also, the columns are not sorted in the way I want.

Suggestions?

SELECT loc, cast(yr as varchar) + '-' + DateName(mm,DATEADD(mm,Mon,-1)) [Period], Amt into #TempTbl FROM TBL WHERE loc = 101 and plID = 11

DECLARE @cols AS VARCHAR(MAX),
    @query  AS VARCHAR(MAX);
    

            pivot 
            (
                 min(Amt)
                for Period in (' + @cols + ')
            ) p '
            
            
SELECT loc, cast(yr as varchar) + '-' + DateName(mm,DATEADD(mm,Mon,-1)) [Period], Amt into #TempTbl FROM TBL WHERE loc = 101 and plID = 11

DECLARE @cols AS VARCHAR(MAX),
    @query  AS VARCHAR(MAX);
    

SELECT @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.[Period]) 
            FROM #TempTbl c
            FOR XML PATH(''), TYPE
            ).value('.', 'VARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT LOC, ' + @cols + ' from 
            (
                select LOC
                    , Amt
                    , [Period]
                from #TempTbl
           ) x
            pivot 
            (
                 min(Amt)
                for Period in (' + @cols + ')
            ) p '

execute(@query)

相关问题