The UPDATE
would happen after the split because from a data state perspective, SQL Server will never overwrite another currently-allocated row in the process.
Moreover, if SQL Server did overwrite a portion of another row, and that row had to be moved, it wouldn't know what data to copy to the new page. A copy of the row could be kept in a temporary buffer in memory... which... is the very definition of a data page.
And so the splitting process goes as follows:
- Allocate a new page
- Copy the split rows to the new page
- Deallocate the split rows from the original page
- Did we reach at least the target amount of free space? If yes, we're done; if no, split again.
Finally, the UPDATE
occurs, which is always free to overwrite unallocated portions of the page.
A PIVOT statement, given all its hard-coding, is a glorified CASE statement. It was easier to build out a UNION query with all the counters, and run CASE statements against the values.
You can definitely convert this into dynamic SQL for future reference, but this is a good start.
SELECT [AccountID],
[SiteID],
[ThreatName],
SUM(ISNULL([08/2016], 0)) as [08/2016],
SUM(ISNULL([09/2016], 0)) as [09/2016],
SUM(ISNULL([10/2016], 0)) as [10/2016],
SUM(ISNULL([08/2016], 0) + ISNULL([09/2016], 0) + ISNULL([10/2016], 0)) AS [Quarterly_Total]
FROM (
SELECT
[account_id] AS [AccountID],
[site_id] AS [SiteID],
'IRA' AS [ThreatName],
SUM(CASE WHEN [Month] = 'August,2016' AND [IRA] IS NOT NULL THEN [IRA] END) AS [08/2016],
SUM(CASE WHEN [Month] = 'September,2016' AND [IRA] IS NOT NULL THEN [IRA] END) AS [09/2016],
SUM(CASE WHEN [Month] = 'October,2016' AND [IRA] IS NOT NULL THEN [IRA] END) AS [10/2016]
FROM
[dbo].[pivoter]
GROUP BY [account_id],[site_id],[Month]
UNION
SELECT
[account_id] AS [AccountID],
[site_id] AS [SiteID],
'RFI' AS [ThreatName],
SUM(CASE WHEN [Month] = 'August,2016' AND [RFI] IS NOT NULL THEN [RFI] END) AS [08/2016],
SUM(CASE WHEN [Month] = 'September,2016' AND [RFI] IS NOT NULL THEN [RFI] END) AS [09/2016],
SUM(CASE WHEN [Month] = 'October,2016' AND [RFI] IS NOT NULL THEN [RFI] END) AS [10/2016]
FROM
[dbo].[pivoter]
GROUP BY [account_id],[site_id],[Month]
UNION
SELECT
[account_id] AS [AccountID],
[site_id] AS [SiteID],
'XSS' AS [ThreatName],
SUM(CASE WHEN [Month] = 'August,2016' AND [XSS] IS NOT NULL THEN [XSS] END) AS [08/2016],
SUM(CASE WHEN [Month] = 'September,2016' AND [XSS] IS NOT NULL THEN [XSS] END) AS [09/2016],
SUM(CASE WHEN [Month] = 'October,2016' AND [XSS] IS NOT NULL THEN [XSS] END) AS [10/2016]
FROM
[dbo].[pivoter]
GROUP BY [account_id],[site_id],[Month]
UNION
SELECT
[account_id] AS [AccountID],
[site_id] AS [SiteID],
'SQLi' AS [ThreatName],
SUM(CASE WHEN [Month] = 'August,2016' AND [SQLi] IS NOT NULL THEN [SQLi] END) AS [08/2016],
SUM(CASE WHEN [Month] = 'September,2016' AND [SQLi] IS NOT NULL THEN [SQLi] END) AS [09/2016],
SUM(CASE WHEN [Month] = 'October,2016' AND [SQLi] IS NOT NULL THEN [SQLi] END) AS [10/2016]
FROM
[dbo].[pivoter]
GROUP BY [account_id],[site_id],[Month]
UNION
SELECT
[account_id] AS [AccountID],
[site_id] AS [SiteID],
'BDP' AS [ThreatName],
SUM(CASE WHEN [Month] = 'August,2016' AND [BDP] IS NOT NULL THEN [BDP] END) AS [08/2016],
SUM(CASE WHEN [Month] = 'September,2016' AND [BDP] IS NOT NULL THEN [BDP] END) AS [09/2016],
SUM(CASE WHEN [Month] = 'October,2016' AND [BDP] IS NOT NULL THEN [BDP] END) AS [10/2016]
FROM
[dbo].[pivoter]
GROUP BY [account_id],[site_id],[Month]
) a
GROUP BY [AccountID],
[SiteID],
[ThreatName]
Best Answer
Given this table and data:
You can apply a simple
PIVOT
:Results:
I would just ensure that
Number, seq
is enforced to be unique and thatseq
is either a bit or has a constraint so that it can only be0
or1
.