I have a result set in SQL Server (simplified and with fewer rows):
Name | Last Sale | Delivery Details | Call Date | Details |
---|---|---|---|---|
Smith | 2024-06-13 | Parcels go to side dr | 2024-08-19 | Enquiry re stk |
Smith | 2024-06-13 | Parcels go to side dr | 2024-08-24 | Will call back |
Smith | 2024-06-13 | Parcels go to side dr | 2024-09-01 | Payment Denied |
Johnson | 2024-09-25 | Ring doorbell | 2024-09-26 | Payment Denied |
Johnson | 2024-09-25 | Ring doorbell | 2024-09-30 | Payment Denied |
Johnson | 2024-09-25 | Ring doorbell | 2024-10-02 | Payment Denied |
Johnson | 2024-09-25 | Ring doorbell | 2024-10-04 | Payment Denied |
Johnson | 2024-09-25 | Ring doorbell | 2024-10-15 | Payment Denied |
Currently, using this code:
set @xhtmlbody =
(
select
(
select
Name, Community, LastSale, DelDetails, CallDate, Details
from #Results2 for xml path('row'),type, root('root')).query
(
'<html><head>
<meta charset="utf-8"/>
(: including embedded CSS styling :)
<style>
table <![CDATA[ {border-collapse: collapse; width: 300px;} ]]>
th <![CDATA[ {background-color: #4CAF50; color: white;} ]]>
th, td <![CDATA[ { text-align: left; padding: 8px;} ]]>
tr:nth-child(even) <![CDATA[ {background-color: #f2f2f2;} ]]>
#green <![CDATA[ {background-color: #3366cc;} ]]>
</style>
</head>
<body style="font-family:Arial;">
<table style="width:100%" border="1">
<caption><h1>{sql:variable("@tableCaption")}</h1><h2>Account Activity</h2></caption>
<thead>
<tr>
<th>Name</th>
<th>Last Sale</th>
<th>Delivery Details</th>
<th>Call Date</th>
<th>Details</th>
</tr>
</thead>
<tbody>
{
for $row in /root/row
return <tr>
<td>{data($row/Name)}</td>
<td>{data($row/LastSale)}</td>
<td>{data($row/DelDetails)}</td>
<td>{data($row/CallDate)}</td>
<td>{data($row/Details)}</td>
</tr>
}
</tbody></table>
</body></html>'
));
This produces the result as you would expect, namely repeating the first three columns and then with a different final two. What I would like is to have the following header info per customer, as in:
Name | Last Sale | Delivery Details |
---|---|---|
Smith | 2024-06-13 | Parcels go to side dr |
Call Date | Details |
---|---|
2024-08-19 | Enquiry re stk |
2024-08-24 | Will call back |
2024-09-01 | Payment Denied |
Name | Last Sale | Delivery Details |
---|---|---|
Johnson | 2024-09-25 | Ring doorbell |
Call Date | Details |
---|---|
2024-09-26 | Payment Denied |
2024-09-30 | Payment Denied |
2024-10-02 | Payment Denied |
2024-10-04 | Payment Denied |
2024-10-15 | Payment Denied |
How do I go about this? Is it even possible?
I'm a little out of my comfort zone here, so can't really figure out the next step. I have looked elsewhere for ways to resolve it, but I can't find anything that suits this case.
EDIT - I should add that this is to then generate an email using SQL server, so the splitting of the queries up seems to be impossible?
Please try the following solution.
It simulates grouping by finding unique person names via XQuery distinct-values()
function.
The rest is leveraging XQuery FLWOR expressions to compose XHTML tables per person name on the fly.
Also, it is possible to compose XHTML with one single table just alternating thead and tbody sections.
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (Name VARCHAR(20), [LastSale] DATE, [DeliveryDetails] VARCHAR(30), [CallDate] DATE, Details VARCHAR(30));
INSERT INTO @tbl (Name, [LastSale], [DeliveryDetails], [CallDate], Details) VALUES
('Smith', '2024-06-13', 'Parcels go to side dr', '2024-08-19', 'Enquiry re stk'),
('Smith', '2024-06-13', 'Parcels go to side dr', '2024-08-24', 'Will call back'),
('Smith', '2024-06-13', 'Parcels go to side dr', '2024-09-01', 'Payment Denied'),
('Johnson', '2024-09-25', 'Ring doorbell', '2024-09-26', 'Payment Denied'),
('Johnson', '2024-09-25', 'Ring doorbell', '2024-09-30', 'Payment Denied'),
('Johnson', '2024-09-25', 'Ring doorbell', '2024-10-02', 'Payment Denied'),
('Johnson', '2024-09-25', 'Ring doorbell', '2024-10-04', 'Payment Denied'),
('Johnson', '2024-09-25', 'Ring doorbell', '2024-10-15', 'Payment Denied')
-- DDL and sample data population, end
DECLARE @xhtmlbody XML;
set @xhtmlbody =
(
select
(
SELECT Name, LastSale, [DeliveryDetails], CallDate, Details
FROM @tbl
ORDER BY Name
FOR xml path('row'),type, root('root')).query
(
'<html><head>
<meta charset="utf-8"/>
(: including embedded CSS styling :)
<style>
table <![CDATA[ {border-collapse: collapse; width: 300px;} ]]>
th <![CDATA[ {background-color: #4CAF50; color: white;} ]]>
th, td <![CDATA[ { text-align: left; padding: 8px;} ]]>
tr:nth-child(even) <![CDATA[ {background-color: #f2f2f2;} ]]>
#green <![CDATA[ {background-color: #3366cc;} ]]>
</style>
</head>
<body style="font-family:Arial;">
{
for $person in distinct-values(/root/row/Name)
return
(<table style="width:100%" border="1">
(:<caption><h1>{sql:variable("@tableCaption")}</h1><h2>Account Activity</h2></caption>:)
<thead>
<tr>
<th>Name</th>
<th>Last Sale</th>
<th>Delivery Details</th>
</tr>
</thead>
<tbody>
{
for $row in /root/row[(Name/text())[1] eq $person][1]
return <tr>
<td>{data($row/Name)}</td>
<td>{data($row/LastSale)}</td>
<td>{data($row/DeliveryDetails)}</td>
</tr>
}
</tbody></table>,
<table>
<thead>
<tr>
<th>Call Date</th>
<th>Details</th>
</tr>
</thead>
<tbody>
{
for $row in /root/row[(Name/text())[1] eq $person]
return <tr>
<td>{data($row/CallDate)}</td>
<td>{data($row/Details)}</td>
</tr>
}
</tbody>
</table>)
}
</body></html>'
));
SELECT @xhtmlbody;
Output
<html>
<head>
<meta charset="utf-8" />
<style>
table {border-collapse: collapse; width: 300px;}
th {background-color: #4CAF50; color: white;}
th, td { text-align: left; padding: 8px;}
tr:nth-child(even) {background-color: #f2f2f2;}
#green {background-color: #3366cc;}
</style>
</head>
<body style="font-family:Arial;">
<table style="width:100%" border="1">
<thead>
<tr>
<th>Name</th>
<th>Last Sale</th>
<th>Delivery Details</th>
</tr>
</thead>
<tbody>
<tr>
<td>Johnson</td>
<td>2024-09-25</td>
<td>Ring doorbell</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Call Date</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<tr>
<td>2024-09-26</td>
<td>Payment Denied</td>
</tr>
<tr>
<td>2024-09-30</td>
<td>Payment Denied</td>
</tr>
<tr>
<td>2024-10-02</td>
<td>Payment Denied</td>
</tr>
<tr>
<td>2024-10-04</td>
<td>Payment Denied</td>
</tr>
<tr>
<td>2024-10-15</td>
<td>Payment Denied</td>
</tr>
</tbody>
</table>
<table style="width:100%" border="1">
<thead>
<tr>
<th>Name</th>
<th>Last Sale</th>
<th>Delivery Details</th>
</tr>
</thead>
<tbody>
<tr>
<td>Smith</td>
<td>2024-06-13</td>
<td>Parcels go to side dr</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Call Date</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<tr>
<td>2024-08-19</td>
<td>Enquiry re stk</td>
</tr>
<tr>
<td>2024-08-24</td>
<td>Will call back</td>
</tr>
<tr>
<td>2024-09-01</td>
<td>Payment Denied</td>
</tr>
</tbody>
</table>
</body>
</html>