Search code examples
htmlsql-serverxquery

Highlight row in HTML table in SQL if the row exists in another table


I use this query to send alerts. I would like a row to be highlighted if a Group ID is in the #GroupsProcessed table, but not to show any additional columns. The status is always the same for the whole group.

drop table #Test
drop table #GroupsProcessed

CREATE TABLE #Test (GroupID INT, UserID INT, Status VARCHAR(5))
INSERT INTO #Test
VALUES  (1,4357, 'A'),
        (1,3492, 'A'),
        (1,3576, 'A'),
        (2,2457, 'B'),
        (3,9458, 'C'),
        (3,8765, 'C'),
        (4,5835, 'D'),
        (5,6654, 'E'),
        (5,4739, 'E'),
        (5,1366, 'E')

CREATE TABLE #GroupsProcessed (GroupID INT, UserID INT)
INSERT INTO #GroupsProcessed
VALUES  (1,4357),
        (1,3492),
        (1,3576),
        (4,5835)
DECLARE @xmlBody        XML   


SET @xmlBody = (SELECT (SELECT DISTINCT  f.GroupID
                                        ,(STUFF((SELECT ', ' + convert(varchar(10),UserID, 120)
                                                  FROM #Test u 
                                                  WHERE    f.GroupID = u.GroupID
                                                  FOR XML PATH ('')), 1, 1, '')) AS UserID
                                        ,Status
                        FROM #Test              f WITH(NOLOCK) 
                        LEFT JOIN #GroupsProcessed o WITH(NOLOCK) ON o.GroupID = f.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> User ID </th>
                <th> Status </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/UserID)}</td>        
                <td>{data($row/Status)}</td>    
                </tr>}
                </tbody></table></body></html>'));

Result I have

enter image description here

Result I would like to have

enter image description here


Solution

  • Please try the following solution.

    Notable points:

    • Added o.GroupID AS highlight to the SELECT clause.
    • Added special yellow class to the CSS section in the XQuery.
    • Added dynamic attribute class to the <tr> element based on the presence of the <highlight> tag.

    SQL

    DECLARE @Test TABLE  (GroupID INT, UserID INT, Status VARCHAR(5));
    INSERT INTO @Test VALUES  
    (1,4357, 'A'),
    (1,3492, 'A'),
    (1,3576, 'A'),
    (2,2457, 'B'),
    (3,9458, 'C'),
    (3,8765, 'C'),
    (4,5835, 'D'),
    (5,6654, 'E'),
    (5,4739, 'E'),
    (5,1366, 'E');
    
    DECLARE @GroupsProcessed TABLE  (GroupID INT, UserID INT)
    INSERT INTO @GroupsProcessed VALUES  
    (1,4357),
    (1,3492),
    (1,3576),
    (4,5835);
    
    DECLARE @xmlBody XML   
    
    SET @xmlBody = (SELECT (
    SELECT DISTINCT  f.GroupID
        ,(STUFF((SELECT ', ' + convert(varchar(10),UserID, 120)
                    FROM @Test AS u 
                    WHERE f.GroupID = u.GroupID
                    FOR XML PATH ('')), 1, 2, '')) AS UserID
        ,Status, o.GroupID AS highlight
    FROM @Test AS f 
    LEFT JOIN @GroupsProcessed AS o ON o.GroupID = f.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.yellow td <![CDATA[ {background-color: yellow;} ]]>
        </style></head>
    <body>
        <table border="1" cellpadding="10" style="border-collapse:collapse;">
        <thead>
            <tr>
                <th>No.</th>
                <th> Group ID </th>
                <th> User ID </th>
                <th> Status </th>
            </tr>
        </thead>
        <tbody>
            {for $row in /root/row
            let $pos := count(root/row[. << $row]) + 1
            return <tr align="center" valign="center">
            {if ($row/highlight) then attribute class {"yellow"} else ()}
            <td>{$pos}</td>
            <td>{data($row/GroupID)}</td>
            <td>{data($row/UserID)}</td>        
            <td>{data($row/Status)}</td>    
        </tr>}
        </tbody>
    </table>
    </body></html>'));
    
    SELECT @xmlBody;
    

    Output in a browser

    enter image description here