recherche

Maison  >  Questions et réponses  >  le corps du texte

Tableau HTML fusionner des cellules en SQL

J'utilise cette requête pour créer un tableau HTML et l'envoyer par e-mail. Est-il possible de fusionner des cellules pour améliorer la lisibilité uniquement lorsque les colonnes « ID de groupe » et « Somme totale des transactions » ont la même valeur ? Voici le résultat que je souhaite obtenir

CREATE TABLE #list (GroupID int,AccountID int,Country varchar (20),AccountTransactionSum int)

Insert into #list
values 
(1,18754,'United Kingdom',110),
(1,24865,'Germany',265),
(1,82456,'Poland',1445),
(1,98668,'United Kingdom',60),
(1,37843,'France',1490),
(2,97348,'United Kingdom',770)

DECLARE @xmlBody      XML   
SET @xmlBody = (SELECT (SELECT  GroupID,                        AccountID,                      Country,            AccountTransactionSum,          TotalTransactionSum = sum(AccountTransactionSum) over (partition by GroupID)
                        FROM #list
                        ORDER BY GroupID 
                        FOR XML PATH('row'), TYPE, ROOT('root')).query('<html><head><meta charset="utf-8"/><style>
                                                                            table <![CDATA[ {border-collapse: collapse; } ]]>
                                                                            th <![CDATA[ {background-color: #4CAF50; color: white;} ]]>
                                                                            th, td <![CDATA[ { text-align: center; padding: 8px;} ]]>
                                                                            tr:nth-child(even) <![CDATA[ {background-color: #f2f2f2;} ]]>
                                                                            </style></head>
                                                                            <body><table border="1" cellpadding="10" style="border-collapse:collapse;">
                                                                            <thead><tr>
                                                                            <th>No.</th>
                                                                            <th> Group ID </th><th> Account ID </th><th> Country </th><th> Account Transaction Sum </th><th> Total Transaction Sum </th>
                                                                            </tr></thead>
                                                                            <tbody>
                                                                            {for $row in /root/row
                                                                            let $pos := count(root/row[. << $row]) + 1
                                                                            return <tr align="center" valign="center">
                                                                            <td>{$pos}</td>
                                                                            <td>{data($row/GroupID)}</td><td>{data($row/AccountID)}</td><td>{data($row/Country)}</td><td>{data($row/AccountTransactionSum)}</td><td>{data($row/TotalTransactionSum)}</td>
                                                                            </tr>}
                                                                            </tbody></table></body></html>'));

    
select @xmlBody

Les résultats que j'ai obtenus

Les résultats que je veux

Lien vers l'éditeur HTML https://codebeautify.org/real-time-html-editor/y237bf87d

P粉005105443P粉005105443274 Il y a quelques jours516

répondre à tous(2)je répondrai

  • P粉310931198

    P粉3109311982024-03-31 14:04:19

    À la très bonne réponse de Siggemannen, je veux juste ajouter une manière alternative de gérer ces td dans xquery,

    SELECT  GroupID, 
            AccountID, 
            Country, 
            AccountTransactionSum,
            TotalTransactionSum = sum(AccountTransactionSum) over (partition by GroupID),
            rowspan = COUNT(*) OVER(PARTITION BY GroupID),
            display = CASE WHEN lag(GroupID) OVER(ORDER BY GroupID,AccountID) = GroupID THEN 'display:none' ELSE '' END
    FROM #list

    Après avoir défini la durée de ligne et l'affichage, vous pouvez les utiliser dans xquery for loop

    for $row in /root/row
    let $pos := count(root/row[. << $row]) + 1
    return 
    
     {$pos}
     {data($row/GroupID)}
     {data($row/AccountID)}
     {data($row/Country)}
     {data($row/AccountTransactionSum)}
     {data($row/TotalTransactionSum)}
    

    répondre
    0
  • P粉754473468

    P粉7544734682024-03-31 12:15:21

    C'est une excellente question car je n'avais aucune idée que xquery pouvait opérer cette magie ! Voici ce que j'ai trouvé :

    DROP TABLE #list
    go
    SELECT  *
    INTO    #list
    FROM    (
    VALUES 
    (1,18754,'United Kingdom',110),
    (1,24865,'Germany',265),
    (1,82456,'Poland',1445),
    (1,98668,'United Kingdom',60),
    (1,37843,'France',1490),
    (2,97348,'United Kingdom',770)
    ) t (groupid,accountid, country, AccountTransactionSum)
    
    DECLARE @xmlBody      XML   
    SET @xmlBody = (SELECT  (SELECT GroupID, 
                                    AccountID, 
                                    Country, 
                                    AccountTransactionSum,
                                    TotalTransactionSum = sum(AccountTransactionSum) OVER (partition BY GroupID),
                                    COUNT(*) OVER(PARTITION BY GroupID) AS rowspan,
                                    CASE WHEN lag(GroupID) OVER(ORDER BY groupid,accountid) = GroupID THEN 1 ELSE 0 END AS skipTd
                            FROM    #list ll
                            ORDER BY GroupID, accountid
                            FOR XML PATH('row'), TYPE, ROOT('root')).query('
                                                                                
                                                                                {for $row in /root/row
                                                                                let $pos := count(root/row[. << $row]) + 1
    
                                                                                return 
                                                                                if ($row/skipTd > 0) then
                                                                                
                                                                                else
                                                                                if ($row/rowspan > 1) then
                                                                                
                                                                                
                                                                                else
                                                                                
                                                                                }
                                                                                
    No. Group ID Account ID Country Account Transaction Sum Total Transaction Sum
    {$pos} {data($row/AccountID)} {data($row/Country)} {data($row/AccountTransactionSum)}
    {$pos} {data($row/GroupID)} {data($row/AccountID)} {data($row/Country)} {data($row/AccountTransactionSum)} {data($row/TotalTransactionSum)}
    {$pos} {data($row/GroupID)} {data($row/AccountID)} {data($row/Country)} {data($row/AccountTransactionSum)} {data($row/TotalTransactionSum)}
    ')); SELECT @xmlBody

    En gros, j'ai créé deux colonnes, rowspan et skipTd. Le premier contrôle si le rowspan doit être appliqué, et le second indique si le actuel doit être ignoré puisqu'il appartient au même groupe.

    J'ai ensuite ajouté un if imbriqué à xquery afin qu'il renvoie du HTML en lignes, "skip" ou normal en fonction de ces deux indicateurs. Il existe peut-être une meilleure façon, je ne suis pas un expert.

    répondre
    0
  • Annulerrépondre