合并SQL Server中的HTML表行

时间:2018-10-16 07:30:51

标签: sql sql-server html-table merge

我正在SQL Server中生成以下字符串,该字符串由员工的薪水数据组成,行数根据每个员工获得的薪水成分而变化。对于任何两个给定的雇员,甚至工资类型也不是固定的。几乎所有的薪酬构成都会根据员工的经验,职位,资历等而有所不同,

<table style="color: #000066; border-collapse: collapse; font-family: Arial,sans-serif; width: 100%; font-size: 10.0pt;" border="1" cellpadding="5">
<tbody>
<tr style="text-align: center;">
<th>Pay Type</th>
<th>Pay Desc</th>
<th>Pay Freq</th>
<th>Currency</th>
<th>Amount</th>
<th>Per Annum</th>
</tr>
<tr>
<td>Salary</td>
<td>Basic Salary</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">23750.00</td>
<td style="text-align: center;">285000.00</td>
</tr>
<tr>
<td>Salary</td>
<td>House Rent Allowance</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">11875.00</td>
<td style="text-align: center;">142500.00</td>
</tr>
<tr>
<td>Salary</td>
<td>Conveyance Allowance</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">1600.00</td>
<td style="text-align: center;">19200.00</td>
</tr>
<tr>
<td>Salary</td>
<td>Education Allowance</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">200.00</td>
<td style="text-align: center;">2400.00</td>
</tr>
<tr>
<td>Salary</td>
<td>Fp Bal</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">34550.00</td>
<td style="text-align: center;">414600.00</td>
</tr>
<tr>
<td>Salary</td>
<td>Ecal</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">144000.00</td>
<td style="text-align: center;">144000.00</td>
</tr>
<tr>
<td>Salary</td>
<td>Retention Pay</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">105000.00</td>
<td style="text-align: center;">105000.00</td>
</tr>
<tr>
<td>Reimbursements</td>
<td>Medical Reimb. Normal</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">25000.00</td>
<td style="text-align: center;">300000.00</td>
</tr>
<tr>
<td>Reimbursements</td>
<td>Phone, Datacard, Landline</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">2800.00</td>
<td style="text-align: center;">33600.00</td>
</tr>
<tr>
<td>Reimbursements</td>
<td>Phone</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">1000.00</td>
<td style="text-align: center;">1000.00</td>
</tr>
<tr>
<td>Reimbursements</td>
<td>Datacard</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">833.00</td>
<td style="text-align: center;">833.00</td>
</tr>
<tr>
<td>Reimbursements</td>
<td>Spectacle</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">2500.00</td>
<td style="text-align: center;">2500.00</td>
</tr>
<tr>
<td>Benefits</td>
<td>Car Valuation (New Car Scheme)</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">3500.00</td>
<td style="text-align: center;">42000.00</td>
</tr>
<tr>
<td>Benefits</td>
<td>Leave Travel Allowance</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">2084.00</td>
<td style="text-align: center;">25008.00</td>
</tr>
<tr>
<td>Benefits</td>
<td>Bonus</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">12584.00</td>
<td style="text-align: center;">151008.00</td>
</tr>
<tr>
<td>Benefits</td>
<td>Esop</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">282716.00</td>
<td style="text-align: center;">282716.00</td>
</tr>
<tr>
<td>Retirement Benefits</td>
<td>Employee Pf</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">2850.00</td>
<td style="text-align: center;">34200.00</td>
</tr>
<tr>
<td>Retirement Benefits</td>
<td>Employee Gratuity</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">1000.00</td>
<td style="text-align: center;">12000.00</td>
</tr>
</tbody>
</table>

如果观察第一列,则大多数数据是重复的。是否可以合并第一列的行,具体取决于它在sql server中包含的数据。这样字符串就如下所示。

<table style="color: #000066; border-collapse: collapse; font-family: Arial,sans-serif; width: 100%; font-size: 10.0pt;" border="1" cellpadding="5">
<tbody>
<tr style="text-align: center;">
<th>Pay Type</th>
<th>Pay Desc</th>
<th>Pay Freq</th>
<th>Currency</th>
<th>Amount</th>
<th>Per Annum</th>
</tr>
<tr>
<td  rowspan="7">Salary</td>
<td>Basic Salary</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">23750.00</td>
<td style="text-align: center;">285000.00</td>
</tr>
<tr>
<td>House Rent Allowance</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">11875.00</td>
<td style="text-align: center;">142500.00</td>
</tr>
<tr>
<td>Conveyance Allowance</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">1600.00</td>
<td style="text-align: center;">19200.00</td>
</tr>
<tr>
<td>Education Allowance</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">200.00</td>
<td style="text-align: center;">2400.00</td>
</tr>
<tr>
<td>Fp Bal</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">34550.00</td>
<td style="text-align: center;">414600.00</td>
</tr>
<tr>
<td>Ecal</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">144000.00</td>
<td style="text-align: center;">144000.00</td>
</tr>
<tr>
<td>Retention Pay</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">105000.00</td>
<td style="text-align: center;">105000.00</td>
</tr>
<tr>
<td rowspan="5">Reimbursements</td>
<td>Medical Reimb. Normal</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">25000.00</td>
<td style="text-align: center;">300000.00</td>
</tr>
<tr>
<td>Phone, Datacard, Landline</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">2800.00</td>
<td style="text-align: center;">33600.00</td>
</tr>
<tr>
<td>Phone</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">1000.00</td>
<td style="text-align: center;">1000.00</td>
</tr>
<tr>
<td>Datacard</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">833.00</td>
<td style="text-align: center;">833.00</td>
</tr>
<tr>
<td>Spectacle</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">2500.00</td>
<td style="text-align: center;">2500.00</td>
</tr>
<tr>
<td rowspan="4">Benefits</td>
<td>Car Valuation (New Car Scheme)</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">3500.00</td>
<td style="text-align: center;">42000.00</td>
</tr>
<tr>
<td>Leave Travel Allowance</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">2084.00</td>
<td style="text-align: center;">25008.00</td>
</tr>
<tr>
<td>Bonus</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">12584.00</td>
<td style="text-align: center;">151008.00</td>
</tr>
<tr>
<td>Esop</td>
<td style="text-align: center;">Yearly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">282716.00</td>
<td style="text-align: center;">282716.00</td>
</tr>
<tr>
<td rowspan="2">Retirement Benefits</td>
<td>Employee Pf</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">2850.00</td>
<td style="text-align: center;">34200.00</td>
</tr>
<tr>
<td>Employee Gratuity</td>
<td style="text-align: center;">Monthly</td>
<td style="text-align: center;">INR</td>
<td style="text-align: center;">1000.00</td>
<td style="text-align: center;">12000.00</td>
</tr>
</tbody>
</table>

以下是我查询此字符串的方法。

set @tabSalary=N'<table cellpadding="5" style="color:#000066;border-collapse: collapse;font-family:Arial,sans-serif;width:100%;font-size: 10.0pt;" border="1">'
    + N'<tr style="text-align:center;"><th>Pay Type</th><th>Pay Desc</th><th>Pay Freq</th><th>Currency</th><th>Amount</th>
    <th>Per Annum</th>
    </tr>'
    + CAST((
        SELECT  isnull(p.PayTypeDesc,'') AS td,
                isnull(dbo.ProperCase(p.PayDesc),'') AS td,
                isnull(p.PayFrequency,'')  as tda,
                 isnull(p.Currency,'') as tda,
                isnull(cast(p.PerMonth as varchar),'') as tda,
                isnull(cast(p.PerAnnum as varchar),'') as tda
        FROM   #saltmp p
        order by p.sort1, p.sort2
        FOR XML RAW('tr'), ELEMENTS
    ) AS NVARCHAR(MAX))
    + N'</table>'
    SET @tabSalary = REPLACE(@tabSalary, '<tda>', '<td style="text-align:center;">')
    SET @tabSalary = REPLACE(@tabSalary, '</tda>', '</td>')

1 个答案:

答案 0 :(得分:0)

以下是我的解决方案。相当复杂。

之前的一些注意事项:

  • 我个人不会在SQL Server中推荐这种处理方式,因为它并未针对这些处理进行优化
  • 由于您的HTML,CSS,event-handlig等具有可维护性和灵活性,因此应在您的前端进行此操作。
  • 尽管如此,从SQL的角度来看,这样的查询还是一个挑战,因此希望这也可以帮助您和其他人
DECLARE 
    @rowsHtml NVARCHAR(MAX), @htmlASxml XML;

;WITH CTE AS (
    SELECT 
        DENSE_RANK() OVER (ORDER BY p.PayTypeDesc) AS PayTypeDesc_GroupSortingIndex,
        ROW_NUMBER() OVER (PARTITION BY p.PayTypeDesc ORDER BY p.sort1, p.sort2) AS PayTypeDesc_GroupInnerSortingIndex,
        COUNT(*) OVER (PARTITION BY p.PayTypeDesc) AS PayTypeDesc_Count,
        ISNULL(p.PayTypeDesc,'') AS PayTypeDesc,
        ISNULL(p.PayDesc,'') AS PayDesc,
        ISNULL(p.PayFrequency,'')  AS PayFrequency,
        ISNULL(p.Currency,'') AS Currency,
        ISNULL(CAST(p.PerMonth AS VARCHAR(10)),'') AS PerMonth,
        ISNULL(CAST(p.PerAnnum AS VARCHAR(10)),'') AS PerAnnum
    FROM #saltmp p
)
SELECT @htmlASxml = (
    SELECT
        PayTypeDesc_Count AS 'PayTypeDesc/@rowspan',
        PayTypeDesc,
        PayDesc,
        PayFrequency,
        Currency,
        PerMonth,
        PerAnnum
    FROM (
        SELECT 
            PayTypeDesc_Count,
            PayTypeDesc,
            PayDesc,
            PayFrequency,
            Currency,
            PerMonth,
            PerAnnum,
            PayTypeDesc_GroupSortingIndex,
            PayTypeDesc_GroupInnerSortingIndex
        FROM CTE
        WHERE PayTypeDesc_GroupInnerSortingIndex = 1
        UNION ALL
        SELECT 
            null,null,
            PayDesc,
            PayFrequency,
            Currency,
            PerMonth,
            PerAnnum,
            PayTypeDesc_GroupSortingIndex,
            PayTypeDesc_GroupInnerSortingIndex
        FROM CTE
        WHERE PayTypeDesc_GroupInnerSortingIndex != 1
    ) as D 
    ORDER BY PayTypeDesc_GroupSortingIndex, PayTypeDesc_GroupInnerSortingIndex
    FOR XML PATH('tr')
);

这是您应该执行的替换操作的屏幕截图。 (我不知道为什么,但是发布答案时我的一些单引号字符串没有显示)

enter image description here

请不要忘记投票,并在适当的时候接受这个答案。 谢谢!