Maison > Questions et réponses > le corps du texte
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粉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)}
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('
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)} |
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 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. actuel doit être ignoré puisqu'il appartient au même groupe.