transposer les lignes de colonnes dans SQL

voix
1

J'ai problème à obtenir la sortie désirée avec la requête SQL.

Mes données SQL est la suivante:

TOTAL   Charge      PAYMNET      A         B        C          D       E      MonthYear
------- ----------- ----------- --------- -------- ---------- ------- ------- ----------
661     157832.24   82967.80    700.00    10.70    58329.33   0.00    0.00    Oct-2013
612     95030.52    17824.28    850.00    66.10    53971.41   0.00    0.00    Nov-2013
584     90256.35    16732.91    700.00    66.10    52219.87   0.00    0.00    Dec-2013
511     72217.32    12336.12    285.00    53.17    42951.12   0.00    0.00    Jan-2014

J'ai besoin de la sortie comme suit,

Data            Jan-2013            Feb-2013            Mar-2013

TOTALCOUNT      761                 647                 671
Charge          126888              119995              151737.5
Payment         25705.4             26235.47            28704.41
A               1089.08             1020                745
B               2100.4              1947.25             1868.22
C               94246.55            84202.15            115673.7
D               0                   0                   0
E               0                   0                   0

J'ai vu les exemples de pivotet unpivot, dans pivotje ne reçois pas les en- têtes de colonnes en tant que données de ligne, et unpivotje ne l' ai pas trouvé un exemple où je peux transposer plusieurs colonnes. J'ai une autre option pour obtenir ce résultat dans le code. Mais je veux savoir est - il possible d'obtenir ce genre de résultat dans sql?

modifier

Le résultat donnera seulement pour 3 ou 4 mois, pas plus que cela.

Mise à jour : Les premières données de l' échantillon est les données réelles que je vais obtenir à la suite de plusieurs jointures et regroupement sur plusieurs tables, que je stocker dans une table temporaire. J'ai essayé d'obtenir le résultat souhaité en modifiant la requête qui est impossible en raison de la structure de la table. J'ai réussi à obtenir le résultat que dans les premières données de l' échantillon, mais ce n'est pas ce que le client veut voir !!! Donc , je dois traiter les données de la table temporaire qui sera seulement 3 à 4 lignes en sortie requise. La requête pour obtenir le premier résultat est select * from temp. Le traitement doit être fait sur temprésultat de la table.

Mise à jour-2

J'ai essayé la requête suivante

declare @cols varchar(max)
select @cols = STUFF((select ', ' + MonthYear
                      from #tmp for xml path('')),1,1,'')

declare @query varchar(max)
set @query = 
        'select ''TOTAL'' as Data,' +@cols+' from
        (select MonthYear,TOTALCLAIMS from #tmp)st
        pivot
        (
            MAX(TOTAL) for MonthYear in (' + @cols + ')
        )pt;'

Ce qui m'a donné la première ligne correctement !!! Mais j'ai essayé d'utiliser unioncomme

set @query = 
        'select ''TOTAL'' as Data,' +@cols+' from
        (select MonthYear,TOTALCLAIMS from #tmp)st
        pivot
        (
            MAX(TOTAL) for MonthYear in (' + @cols + ')
        )pt;
        union
        select ''CHARGES'' as Data,' +@cols+' from
        (select MonthYear,TOTALCLAIMS from #tmp)st
        pivot
        (
            MAX(CHARGES) for MonthYear in (' + @cols + ')
        )pt;'

Ce qui donne une erreur incorrect syntax near union. Quelqu'un sait comment l' union des pivotrésultats? Ou est - il une meilleure façon de le faire?

Je vous remercie.

Créé 27/03/2014 à 10:30
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
1

J'ai essayé ce code. S'il vous plaît vérifier et laissez-moi savoir si cela fonctionne

Je sais qu'il a pas l'air si bon. Aussi ne sais pas comment il sera sage performance.

--Can have more columns like A,B,...
DECLARE @tbl TABLE
(
TOTAL INT,
CHARGE FLOAT,
PAYMENT FLOAT,
MONTHYEAR VARCHAR(50)
)


--Test data
INSERT IGNORE  INTO @tbl SELECT 661, 157832.24, 82967.80, 'Oct2013'
INSERT IGNORE  INTO @tbl SELECT 612,     95030.52,    17824.28, 'Nov2013'
INSERT IGNORE  INTO @tbl SELECT 584     ,90256.35,    16732.91, 'Dec2013'

--Can be a physical table
CREATE TABLE #FinalTbl 
(
DATA VARCHAR(100)
)

--inserted hardcode records in data column. To add it dynamically you would need to loop through information_schema.columns
--SELECT *
--FROM information_schema.columns
--WHERE table_name = 'tbl_name'
INSERT IGNORE  INTO #FinalTbl
VALUES ('TOTAL')

INSERT IGNORE  INTO #FinalTbl
VALUES ('CHARGE')

INSERT IGNORE  INTO #FinalTbl
VALUES ('PAYMENT')

DECLARE @StartCount INT, @TotalCount INT, @Query VARCHAR(5000), @TOTAL INT,@CHARGE FLOAT,@PAYMENT FLOAT,@MONTHYEAR VARCHAR(50)

SELECT @TotalCount = COUNT(*) FROM @tbl;
SET @StartCount = 1;

WHILE(@StartCount <= @TotalCount)
BEGIN
    SELECT @TOTAL = TOTAL, 
    @CHARGE = CHARGE,
    @PAYMENT = PAYMENT,
    @MONTHYEAR = MONTHYEAR  
    FROM
    (SELECT ROW_NUMBER() over(ORDER BY MONTHYEAR) AS ROWNUM, * FROM @tbl) as tbl
    WHERE ROWNUM = @StartCount

    SELECT @Query = 'ALTER TABLE #FinalTbl ADD ' + @MONTHYEAR + ' VARCHAR(1000)'
    EXEC (@Query)

    SELECT @Query = 'UPDATE #FinalTbl SET ' + @MONTHYEAR + ' = ''' + CONVERT(VARCHAR(50), @TOTAL) + ''' WHERE DATA = ''TOTAL'''
    EXEC (@Query)

    SELECT @Query = 'UPDATE #FinalTbl SET ' + @MONTHYEAR + ' = ''' + CONVERT(VARCHAR(50), @CHARGE) + ''' WHERE DATA = ''CHARGE'''
    EXEC (@Query)

    SELECT @Query = 'UPDATE #FinalTbl SET ' + @MONTHYEAR + ' = ''' + CONVERT(VARCHAR(50), @PAYMENT) + ''' WHERE DATA = ''PAYMENT'''
    EXEC (@Query)

    SELECT @StartCount = @StartCount + 1
END

SELECT * FROM #FinalTbl

DROP TABLE #FinalTbl

J'espère que cela t'aides

Créé 27/03/2014 à 12:41
source utilisateur

voix
0
Select Month(Mdate)md,'A' AS Col,sum(A) as a from Product group by Month(MDate)
union all
Select Month(Mdate)md,'B',sum(b) as a from Product group by Month(MDate)
union all
Select Month(Mdate)md,'C',sum(c) as a from Product group by Month(MDate)
union all
Select Month(Mdate)md,'D',Count(A) as a from Product group by Month(MDate)

Essayez Pivotla requête ci - dessus vous pouvez obtenir le résultat nécessaire pour ....

Créé 27/03/2014 à 11:36
source utilisateur

voix
0

J'imagine la raison pour laquelle vous obtenez seulement 3 ou 4 mois est parce que vous ne disposez pas de données pour les mois manquants? Si vous souhaitez afficher des colonnes pour les mois manquants, vous devez soit:

  1. Créer un tableau avec tous les types de données mois que vous souhaitez afficher et à gauche rejoindre le reste des tables dans votre requête. Vous pouvez ensuite utiliser la fonction PIVOT comme normale.

  2. Si vous connaissez le nombre de colonnes à l'avant-à-dire un pour chaque mois d'une année donnée et il ne changera pas, vous pouvez simplement utiliser Argumentaires (un pour chaque mois) pour transposer les données sans que l'opérateur PIVOT.

Je peux donner des exemples si nécessaire.

Créé 27/03/2014 à 11:22
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more