Join Query based on Date - tsql

I have a table that has time scaled values and I need to be able to scale the values. I am trying to make this as simple as possible however speed of execution is a big player for me.
Let me give you an example of the tblTSS_DataCollection:
SELECT TOP 5
[DataPointID]
,[DatapointDate]
,dc.[DataPointValue]
FROM [tblTSS_DataCollection] dc
Where DatapointID = 1093
This here would return a very simple table:
DataPointID DatapointDate DataPointValue
1093 2012-07-29 00:00:01.000 0.01869818
1093 2012-07-29 00:01:01.000 0.01882841
1093 2012-07-29 00:02:01.000 0.01895865
1093 2012-07-29 00:03:01.000 0.01908888
1093 2012-07-29 00:04:01.000 0.01921912
Now I have another table called tblTSS_ScaleSettings which looks like this:
SELECT [ID]
,[DatapointID]
,[EffectiveDate]
,[ScaleType]
,[ScaleValue]
FROM [tblTSS_ScaleSettings]
Which will return a result something like this:
ID DatapointID EffectiveDate ScaleType ScaleValue
1 1093 2012-07-29 00:03:01.000 * 10.0000
Now what I need to be able to do is something like this:
SELECT TOP 5
dc.[DataPointID]
,[DatapointDate]
,dc.[DataPointValue] AS [DVOld]
,CASE sc.ScaleType
WHEN '*' THEN dc.[DataPointValue] * sc.ScaleValue
WHEN '/' THEN dc.[DataPointValue] / sc.ScaleValue
WHEN '+' THEN dc.[DataPointValue] + sc.ScaleValue
WHEN '-' THEN dc.[DataPointValue] - sc.ScaleValue
ELSE dc.[DataPointValue]
END
AS [DatapointValue]
FROM [tblTSS_DataCollection] dc
JOIN [tblTSS_ScaleSettings] sc
on sc.DatapointID = dc.DatapointID
Where dc.DatapointID = 1093
Which would return:
DataPointID DatapointDate DVOld DatapointValue
1093 2012-07-29 00:00:01.000 0.01869818 0.1869818
1093 2012-07-29 00:01:01.000 0.01882841 0.1882841
1093 2012-07-29 00:02:01.000 0.01895865 0.1895865
1093 2012-07-29 00:03:01.000 0.01908888 0.1908888
1093 2012-07-29 00:04:01.000 0.01921912 0.1921912
However, what is wrong with this is because the scaling EffectiveDate in the table doesn't start until 00:03:01 scaling should start then not on all the records. Scaling should be that scale until the next effectivedate. Sometimes we will have multiple Scales that happen and it changes at different times throughout the year. So I need the Select Query to plan for that.... This is where it gets tricky.
Which would look like this:
DataPointID DatapointDate DVOld DatapointValue
1093 2012-07-29 00:00:01.000 0.01869818 0.01869818
1093 2012-07-29 00:01:01.000 0.01882841 0.01882841
1093 2012-07-29 00:02:01.000 0.01895865 0.01895865
1093 2012-07-29 00:03:01.000 0.01908888 0.1908888
1093 2012-07-29 00:04:01.000 0.01921912 0.1921912
Can someone please help?

Something like this might work for you:
SELECT TOP 5
dc.DataPointID
,DatapointDate
,dc.DataPointValue AS DVOld
,CASE sc.ScaleType
WHEN '*' THEN dc.DataPointValue * sc.ScaleValue
WHEN '/' THEN dc.DataPointValue / sc.ScaleValue
WHEN '+' THEN dc.DataPointValue + sc.ScaleValue
WHEN '-' THEN dc.DataPointValue - sc.ScaleValue
ELSE dc.DataPointValue
END
AS DatapointValue
FROM tblTSS_DataCollection dc
LEFT JOIN tblTSS_ScaleSettings sc
ON sc.DatapointID = dc.DatapointID
AND sc.EffectiveDate = (
SELECT MAX(EffectiveDate)
FROM tblTSS_ScaleSettings
WHERE DatapointID = dc.DatapointID
AND EffectiveDate <= dc.DatapointDate
)
WHERE dc.DatapointID = 1093

would a from clause like this work?
FROM [tblTSS_DataCollection] dc
JOIN sc on sc.DatapointID = dc.DatapointID inner join
(
select datapointid, max(effectivedate) as max_dt
from
[tblTSS_ScaleSettings]
where
effectiveDate <= getdate()
group by datapointID
) mx on
sc.datapointid = mx.datapointid and
sc.effectivedate = mx.max_dt
what you entered should be equivalent to:
SELECT TOP 10
dc.[DataPointID]
,[DatapointDate]
,dc.[DataPointValue] AS [DVOld]
,EffectiveDate
,ScaleType
,ScaleValue
,CASE ScaleType
WHEN '*' THEN dc.[DataPointValue] * ScaleValue
WHEN '/' THEN dc.[DataPointValue] / ScaleValue
WHEN '+' THEN dc.[DataPointValue] + ScaleValue
WHEN '-' THEN dc.[DataPointValue] - ScaleValue
ELSE dc.[DataPointValue]
END
AS [DatapointValue]
FROM [tblTSS_DataCollection] dc inner join
(select DatapointID, max(EffectiveDate) as max_effective,
from tblTSS_ScaleSettings ts
where ts.EffectiveDate <= dc.DatapointDate
group by DatapointID) mx
on dc.datapointid = mx.datapointid and
EffectiveDate = max_effective
Where dc.DatapointID = 1093

Related

T-SQL how to assign a variable inside another variable assignment

I've inherited a stored proc and I need to add and assign a new variable. The piece of the code that's relevant is:
DECLARE #tableRows VARCHAR(MAX) = '';
SET #tableRows
= N'<tr>
<bgcolor="#6081A0" style="FONT-FAMILY:arial,san-serif;FONT-WEIGHT:normal;color:#6081A0"> :: Resource Scheduler</tr>'
+ N'<tr>
Date: ' + CAST(CONVERT(NVARCHAR, DATENAME(WEEKDAY, #rpt_start_date)) AS VARCHAR(100)) + ' '
+ CAST(CONVERT(NVARCHAR, CAST(#rpt_start_date AS DATE), 100) AS VARCHAR(100)) + '</tr>'
+ '<table border="1" width="100%">'
+ '<tr bgcolor="#DC5E3F" style="FONT-FAMILY:arial,san-serif;FONT-WEIGHT:bold;color:white">'
+ '<td style="text-align:center;vertical-align:middle">START TIME</td>'
+ '<td style="text-align:center;vertical-align:middle">END TIME</td>'
+ '<td style="text-align:center;vertical-align:middle">ROOM</td>'
+ '<td>MEETING TITLE</td>'
+ '<td style="text-align:center;vertical-align:middle">ATTENDEES</td>'
+ '<td>INVITEE' + CHAR(39) + 'S NAME</td><td>HOSTS NAMES</td>'
+ '<td>FOOD SERVICES REQUESTS</td>'
+ '<td>TECHNOLOGY REQUESTS</td>'
+ '<td>OFFICE SERVICES REQUESTS</td></tr>';
SELECT #tableRows
= #tableRows + '<tr ' + 'bgcolor=' +
+ IIF(ROW_NUMBER() OVER (ORDER BY s.[sched_id] DESC) % 2 = 0, '"lightgrey', '"white') + '">'
+ '<td style="text-align:center;vertical-align:middle">' + CAST(CONVERT(NVARCHAR, CAST(srd.[mtg_start_date_local] AS TIME), 100) AS VARCHAR(100)) + '</td>'
+ '<td style="text-align:center;vertical-align:middle">' + CAST(CONVERT(NVARCHAR, CAST(srd.[mtg_end_date_local] AS TIME), 100) AS VARCHAR(100)) + '</td>'
+ '<td style="text-align:center;vertical-align:middle">' + CAST(r.[res_hdr] AS VARCHAR(100)) + '</td>'
+ '<td>' + CAST(s.[sched_desc] AS VARCHAR(100)) + '</td>'
+ '<td style="text-align:center;vertical-align:middle">' + CAST(s.[num_attendees] AS VARCHAR(100)) + '</td>'
+ '<td>' + CAST(ru.[user_name] AS VARCHAR(100)) + '</td>'
+ '<td>' + CAST(hu.[user_name] AS VARCHAR(100)) + '</td>'
+ '<td>' + CAST(dbo.ufn_rsConcatCustomTabServices(#rs_customtab_food,s.[sched_id]) AS VARCHAR(4000)) + '</td>'
+ '<td>' + CAST(dbo.ufn_rsConcatCustomTabServices(#rs_customtab_tech,s.[sched_id]) AS VARCHAR(4000)) + '</td>'
+ '<td>' + CAST(dbo.ufn_rsConcatCustomTabServices(#rs_customtab_os,s.[sched_id]) AS VARCHAR(4000)) + '</td></tr>'
FROM
tbl_sched s WITH (NOLOCK)
INNER JOIN
tbl_sched_res_date srd WITH (NOLOCK)
ON s.[sched_id] = srd.[sched_id]
INNER JOIN
tbl_sched_request sr WITH (NOLOCK)
ON s.[sched_id] = sr.[sched_id]
INNER JOIN
tbl_user ru WITH (NOLOCK)
ON sr.[req_for_user_id] = ru.[user_id]
INNER JOIN
tbl_user hu WITH (NOLOCK)
ON s.create_by = hu.[user_id]
INNER JOIN
tbl_res r WITH (NOLOCK)
ON srd.[res_id] = r.[res_id]
INNER JOIN
tbl_grp g WITH (NOLOCK)
ON r.[grp_id] = g.[grp_id]
INNER JOIN
tbl_loc l WITH (NOLOCK)
ON g.[loc_id] = l.[loc_id]
INNER JOIN
tbl_region rg WITH (NOLOCK)
ON l.[region_id] = rg.[region_id]
LEFT OUTER JOIN -- changed from inner join
tbl_sched_udf_val suv_f WITH (NOLOCK)
ON suv_f.[sched_id] = s.[sched_id]
AND suv_f.[udf_id] =
(
SELECT
u.[udf_id]
FROM
tbl_udf u WITH (NOLOCK)
WHERE
u.[udf_desc] LIKE #rs_customtab_food
)
AND suv_f.[string_value] IS NOT NULL
AND suv_f.[string_value] = 'Yes'
LEFT OUTER JOIN -- changed from inner join
tbl_sched_udf_val suv_t WITH (NOLOCK)
ON suv_t.[sched_id] = s.[sched_id]
AND suv_t.[udf_id] =
(
SELECT
u.[udf_id]
FROM
tbl_udf u WITH (NOLOCK)
WHERE
u.[udf_desc] LIKE #rs_customtab_tech
)
AND suv_t.[string_value] IS NOT NULL
AND suv_t.[string_value] = 'Yes'
LEFT OUTER JOIN -- changed from inner join
tbl_sched_udf_val suv_o WITH (NOLOCK)
ON suv_o.[sched_id] = s.[sched_id]
AND suv_o.[udf_id] =
(
SELECT
u.[udf_id]
FROM
tbl_udf u WITH (NOLOCK)
WHERE
u.[udf_desc] LIKE #rs_customtab_os
)
AND suv_o.[string_value] IS NOT NULL
AND suv_o.[string_value] = 'Yes'
LEFT OUTER JOIN
tbl_sched_res_setup srs WITH (NOLOCK)
ON (
s.[sched_id] = srs.[sched_id]
AND srd.[res_id] = srs.[res_id]
)
LEFT OUTER JOIN
tbl_setup su WITH (NOLOCK)
ON (srs.[setup_id] = su.[setup_id])
WHERE
l.[loc_id] = 13-- 1177 Sixth Ave ( ONLY )
AND s.[deleted_flag] = 0
AND r.[obsolete_flag] = 0
AND g.[obsolete_flag] = 0
AND l.[obsolete_flag] = 0
AND rg.[obsolete_flag] = 0
AND srd.[busy_start_date_local] >= CONVERT(NVARCHAR(20), #rpt_start_date, 112)
AND srd.[busy_start_date_local] < CONVERT(NVARCHAR(20), #rpt_end_date, 112)
ORDER BY
srd.[mtg_start_date_local],
r.[res_hdr];
SELECT #tableRows = #tableRows + '</table>';
As you can see, it's a complicated query. #tableRows is used later on to create the body of an email. Now, I need to get s.sched_desc (see line 7 of SELECT statement) and assign it to a second variable, so that I can use it in the Subject line of the same email. I've tried adding
+ (SELECT #sched_desc = SELECT [sched_desc])
to the bottom of the SELECT statement but it's no good (incorrect syntax near parenthesis). I've also tried
+ '<td>' + (SELECT #sched_desc = CAST(s.[sched_desc] AS VARCHAR(100))) + '</td>'
but again it's expecting another parenthesis. I know I can do this by turning this whole thing into a string and then executing it with sp_executesql (see this example) but I'd prefer to avoid dynamic sql if possible. On the other hand, I really don't want to execute this query twice. Is there another way to get around this?
Your stated task would be more easily accomplished and supported by employing a templating language and some basic string interpolation.
It is not possible to set a variable value within the process of setting another variable's value, but you can do so within the same SELECT.
In your query, add a comma after the closing quote and then set your #sched_desc variable:
SELECT #tableRows = #tableRows + '<tr ' + 'bgcolor=' ... </td></tr>',
#sched_desc = [sched_desc]
FROM tbl_sched s WITH (NOLOCK)
INNER JOIN tbl_sched_res_date srd WITH (NOLOCK)
ON s.[sched_id] = srd.[sched_id]
...
The second variable assignment has access to the same data as the original query, but it will need to be included in whatever selecting process is used to retrieve the value of #tableRows.
As an additional note, I will strongly advise you to identify alternatives to using NOLOCK - here are some links to get you started on that path:
https://www.brentozar.com/archive/2021/11/nolock-is-bad-and-you-probably-shouldnt-use-it/
https://www.brentozar.com/archive/2018/10/using-nolock-heres-how-youll-get-the-wrong-query-results/
https://www.brentozar.com/archive/2016/12/nolock-ever-right-choice/
https://www.brentozar.com/archive/2021/01/but-surely-nolock-is-okay-if-no-ones-changing-data-right/
Paneerakbari is correct that you can assign (and build up) more than one variable in the select. Here is a simplified example that may make things clearer.
DECLARE #TableRows VARCHAR(MAX) = '<table>'
DECLARE #Subject VARCHAR(MAX) = '' -- Only the last value is retained here
SELECT
#TableRows = #TableRows + '<tr><td>' + A.Info + '</td></tr>',
#Subject = A.Title
FROM (
VALUES
(1, 'This', 'This stuff'),
(2, 'That', 'That stuff'),
(3, 'More', 'More stuff')
) A(ID, Title, Info)
ORDER BY A.ID
SET #TableRows = #TableRows + '</table>'
SELECT #Subject, #TableRows
Result:
#Subject = 'More'
#TableRows = '<table><tr><td>This stuff</td></tr><tr><td>That stuff</td></tr><tr><td>More stuff</td></tr></table>'
For readability and maintainability, I often find it useful to move complex intermediate calculations into a CROSS APPLY block, the results of which can then be referenced in the final select.
DECLARE #TableRows VARCHAR(MAX) = '<table>'
DECLARE #Subject VARCHAR(MAX) = '' -- Only the last value is retained here
SELECT
#TableRows = #TableRows + R.ComplexRowConstruction,
#Subject = A.Title
FROM (
VALUES
(1, 'This', 'This stuff'),
(2, 'That', 'That stuff'),
(3, 'More', 'More stuff')
) A(ID, Title, Info)
CROSS APPLY (
SELECT ComplexRowConstruction =
'<tr>'
+ '<td>' + A.Info + '</td>'
+ '</tr>'
) R
ORDER BY A.ID
SET #TableRows = #TableRows + '</table>'
SELECT #Subject, #TableRows

SQL Server select from temp table into another temp table

I have this in a stored procedure:
select * into #temp_UNION from
(
SELECT 6 AS InteractionType, * FROM history.GetHistoryRewardPointsForIncentiveOption (588,1,6)
UNION all
SELECT 8 AS InteractionType, * FROM history.GetHistoryRewardPointsForIncentiveOption (558,1,8)
) a
which gives:
interaction type historyid incentiveprogramid points
6 1 1 50
6 1 4 50
6 1 5 50
8 1 3 100
8 1 4 100
then i have:
select tu.InteractionType,ipc.Name,tu.Points from #temp_UNION tu
inner join Incentive.IncentiveProgramCultures ipc
on tu.IncentiveProgramId = ipc.IncentivePrograms_IncentiveProgramId
inner join Zinc.Users zu
on zu.Cultures_DefaultCultureId = ipc.IncentiveProgramCultureId
where zu.UserId = 588
6 India - Q2 Incentive 50
8 India - Q2 Incentive 100
now i need to make up HintText which is a field in my #CategoriesTable(previously defined) by using the name i got from above and the points
UPDATE #CategoriesTable
SET HintText = CASE WHEN HasAssessment = 1
THEN 'Program ' + tu.name + ' will earn you ' + tu.points
ELSE 'With No Assessment'
END
but i get an error on tu.Name: multi part identifier could not be bound?
how can i achieve? should i make use of another temp table with the 2 rows in it?
here new code:
select * into #temp_UNION from
(
SELECT 6 AS InteractionType, * FROM history.GetHistoryRewardPointsForIncentiveOption (588,1,6)
UNION all
SELECT 8 AS InteractionType, * FROM history.GetHistoryRewardPointsForIncentiveOption (558,1,8)
) a
select tu.InteractionType,ipc.Name,tu.Points,zu.UserId into #temp1 from #temp_UNION tu
inner join Incentive.IncentiveProgramCultures ipc
on tu.IncentiveProgramId = ipc.IncentivePrograms_IncentiveProgramId
inner join Zinc.Users zu
on zu.Cultures_DefaultCultureId = ipc.IncentiveProgramCultureId
where zu.UserId = 588
Select * from #temp1 t
UPDATE #CategoriesTable
SET HintText = CASE WHEN HasAssessment = 1
THEN 'Program ' + t.Name + ' and points = ' + t.Points
ELSE 'With No Assessment'
END
FROM #temp1 t
WHERE t.userId = #CategoriesTable.UserId
DROP TABLE #temp_UNION
DROP TABLE #temp1
SELECT *
FROM #CategoriesTable
im not getting the #CategoriesTable?
You must specify the "tu" alias in the update clause
UPDATE #CategoriesTable
SET HintText = CASE WHEN HasAssessment = 1
THEN 'Program ' + tu.name + ' will earn you ' + tu.points
ELSE 'With No Assessment'
END
FROM #temp_UNION tu
WHERE tu.? = #CategoriesTable.? --JOIN condition

SQL Server 2008 R2 T-SQL: Recommendations for re-writing code to allow creating a view

I have created a T-SQL query in SQL Server 2008 R2 that is a customization. The code works great as a T-SQL query and returns the correct information. Being new to coding, I was happy with the way SQL returns the data for my query. Unfortunately, I proceeded to write this unaware that #variables cannot be declared, if you are going to create a view.
As such, I am unable to create the view and schedule automatic execution of the report. I am looking for specific hints I can use to re-write this query, if it can be done at all. The software is vCM "VMware Configuration Manager", and my T-SQL query looks up information in a created view and returns statistics relative to installation progress of the software package.
I have searched, and worked with a few close colleagues to try and find the answer before posting here. There are two parts; a created view that does work, which places all of my needed information in a view for easy access. And the second part that is working great in SQL Server Management Studio query window. When I attempt to create the view, I get this specific error.
Msg 156, Level I5, State 1, Procedure ECMCUST_ProgressReport, Line 3
Incorrect syntax near the keyword 'Declare'.
From everything I have found online, it appears a re-write is in order. It also appears this issue can be seen creating views, stored procedures, etc...
A hint on which direction to go, would be awesome.
This creates the VIEW that works
/* ------------------------------------------------------------*/
CREATE VIEW ECMCUST_emcmachineresults as
SELECT a.machine_id, a.machine_name, a.managed, a.[enabled],a.ignored, b.platform_id, b.current_agent_version, c.data_value
FROM ecm_sysdat_machine_state a
JOIN ecm_dat_machines b
ON a.machine_id = b.machine_id
JOIN ecm_sysdat_asset_machine_data c
ON b.machine_id = c.machine_id
where property_id = 3 or property_id =1006
/* ------------------------------------------------------------*/
This is the code that works fine in T-SQL, but I cannot create a view from
/* ------------------------------------------------------------*/
Declare #WinTotal1 as FLOAT
Declare #Ignored1 as FLOAT
Declare #IgnoredException1 as FLOAT
Declare #TotalsR1 as FLOAT
Declare #PercentComplete1 as DECIMAL(3,2)
select #WinTotal1 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 5
select #Ignored1 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 5
and ignored = 1
select #IgnoredException1 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 5
and ignored = 1
and data_value like '*%'
SELECT #TotalsR1 =
(SELECT COUNT(*) FROM ECMCUST_emcmachineresults WHERE platform_id = 5) -
(SELECT COUNT(*) FROM ECMCUST_emcmachineresults WHERE platform_id = 5
and ignored = 1
and data_value != '*%')
SELECT #PercentComplete1 = #TotalsR1/#WinTotal1
/* ------------------------------------------------------------*/
Declare #ESXTotal2 as FLOAT
Declare #Ignored2 as FLOAT
Declare #IgnoredException2 as FLOAT
Declare #TotalsR2 as FLOAT
Declare #PercentComplete2 as DECIMAL(3,2)
select #ESXTotal2 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 11
select #Ignored2 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 11
and ignored = 1
select #IgnoredException2 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 11
and ignored = 1
and data_value like '*%'
SELECT #TotalsR2 =
(SELECT COUNT(*) FROM ECMCUST_emcmachineresults WHERE platform_id = 11)-
(SELECT COUNT(*) FROM ECMCUST_emcmachineresults WHERE platform_id = 11
and ignored = 1
and data_value != '*%')
SELECT #PercentComplete2 = #TotalsR2/#ESXTotal2
/* ------------------------------------------------------------*/
Declare #RHELTotal3 as FLOAT
Declare #Ignored3 as FLOAT
Declare #IgnoredException3 as FLOAT
Declare #TotalsR3 as FLOAT
Declare #PercentComplete3 as DECIMAL(3,2)
select #RHELTotal3 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 2
select #Ignored3 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 2
and ignored = 1
select #IgnoredException3 = COUNT(machine_id)
from [ECMCUST_emcmachineresults]
where platform_id = 2
and ignored = 1
and data_value like '*%'
SELECT #TotalsR3 =
(SELECT COUNT(*) FROM ECMCUST_emcmachineresults WHERE platform_id = 2)-
(SELECT COUNT(*) FROM ECMCUST_emcmachineresults WHERE platform_id = 2
and ignored = 1
and data_value != '*%')
SELECT #PercentComplete3 = #TotalsR3/#RHELTotal3
Select
'Windows' as [Machine Type],
#WinTotal1 AS [Total Servers],
#Ignored1 AS [Ignored Servers],
#IgnoredException1 AS [Ignored Exceptions Servers],
#TotalsR1 AS [Total Managed],
#PercentComplete1 AS [Percent Complete]
union
Select
'ESX' as [Machine Type],
#ESXTotal2 AS [Total Servers],
#Ignored2 AS [Ignored Servers],
#IgnoredException2 AS [Ignored Exceptions Servers],
#TotalsR2 AS [Total Managed],
#PercentComplete2 AS [Percent Complete]
union
Select
'RHEL' as [Machine Type],
#RHELTotal3 AS [Total Servers],
#Ignored3 AS [Ignored Servers],
#IgnoredException3 AS [Ignored Exceptions Servers],
#TotalsR3 AS [Total Managed],
#PercentComplete3 AS [Percent Complete]
union
select
'All' as [Machine Type],
#WinTotal1 + #ESXTotal2 + #RHELTotal3 as [Total Servers],
#Ignored1 + #Ignored2 + #Ignored3 as [Total Ignored],
#IgnoredException1 + #IgnoredException2 + #IgnoredException3 as [Total Ignored Exceptions],
#TotalsR1 + #TotalsR2 + #TotalsR3 as [Total Managed],
(#PercentComplete1+#PercentComplete2+#PercentComplete3)/3 as [Percent Complete]
Create a stored procedure, with all your code should be easiest way.
However, if you really need a view, this should do it (untested)
CREATE VIEW ECMCUST_emcmachineresults
AS
WITH cte1 AS
(
SELECT
platform_id
,SUM(CASE WHEN machine_id IS NOT NULL THEN 1 ELSE 0 END) AS WinTotal
,SUM(CASE WHEN machine_id IS NOT NULL AND ignored = 1 THEN 1 ELSE 0 END) AS Ignored
,SUM(CASE WHEN machine_id IS NOT NULL AND ignored = 1 AND data_value LIKE '*%' THEN 1 ELSE 0 END) AS IgnoredException
,COUNT(*) AS Total
,SUM(CASE WHEN ignored = 1 AND data_value <> '*%' THEN 1 ELSE 0 END) AS R1
FROM [ECMCUST_emcmachineresults]
WHERE platform_id IN (5,11,2)
GROUP BY platform_id
)
, cte2 AS
(
SELECT
CASE
WHEN platform_id = 5 THEN 'Windows'
WHEN platform_id = 11 THEN 'ESX'
WHEN platform_id = 2 THEN 'RHEL'
END AS [Machine Type],
WinTotal AS [Total Servers],
Ignored AS [Ignored Servers],
IgnoredException AS [Ignored Exceptions Servers],
Total - R1 AS [Total Managed],
CAST((Total - R1) * 1.00 /WinTotal AS DECIMAL (3, 2)) AS [Percent Complete]
FROM cte1
)
SELECT
[Machine Type],
[Total Servers],
[Ignored Servers],
[Ignored Exceptions Servers],
[Total Managed],
[Percent Complete]
FROM cte2
UNION ALL
SELECT
'ALL' AS [Machine Type],
SUM([Total Servers]),
SUM([Ignored Servers]),
SUM([Ignored Exceptions Servers]),
SUM([Total Managed]),
SUM([Percent Complete])/3
FROM cte2

Data conversion from columns to rows

I have a record DCP_SC_DOT_TBL where there are 2 keys SETID and CONTRACTID. In addition to this this there are 78 more columns which are checkboxes and contain a value Y or Blank. For example:
SETID CONTRACTID 1 2 3 ...... 78
DCPID 00102 Y Y
DCPID 00192 Y Y Y
Now I want to remove all these columns and create a new row for each non-blank column to create a table, for example, like this:
SETID CONTRACTID Checkbox(New column for all the 78 columns)
DCPID 00102 1
DCPID 00102 3
DCPID 00192 2
DCPID 00192 3
DCPID 00192 78
Can someone please suggest how to achieve this? I want only the column containing some data against the CONTRACTIDs.
In re-reading your post, it sounds like you simply need a large union query:
Select SetId, ContractId, '1' As ColNum,
From SomeTable As S1
Where S1.Col1 = 'Y'
Union All
Select SetId, ContractId, '2'
From SomeTable As S1
Where S1.Col2 = 'Y'
Union All
Select SetId, ContractId, '3'
From SomeTable As S1
Where S1.Col3 = 'Y'
...
Union All
Select SetId, ContractId, '78'
From SomeTable As S1
Where S1.Col78 = 'Y'
If you wanted to result other information from the main table, then you would join this result set to it:
Select
From SomeTable As S
Join (
Select SetId, ContractId, '1' As ColNum,
From SomeTable As S1
Where S1.Col1 = 'Y'
Union All
Select SetId, ContractId, '2'
From SomeTable As S1
Where S1.Col2 = 'Y'
Union All
Select SetId, ContractId, '3'
From SomeTable As S1
Where S1.Col3 = 'Y'
...
Union All
Select SetId, ContractId, '78'
From SomeTable As S1
Where S1.Col78 = 'Y'
) As Z
On Z.SetId = S.SetId
And Z.ContractId = S.ContractId

Need to pivot or crosstab a table but not in the conventional way. please

I have a small situation here.. hope you guys can help me out.
I'm supposed to query a table wich has 4 columns
AccountNo, ResourceNo, ProductNo, CustomerNo.
A few accountNo's have 2 ResourceNo's (115 and 134)
I have to Query it in such a way that I have to show two dynamic columns for the resourceNo values and put an 'X' against the accountNo which has those ResourceNo's.. So that the AccountNo is not repeated.. Pivoting doesn't help in this situation. Please look into this and help me.
See also
Poor Man's SQL Pivot.
See also
Sql Pivot Query with Dynamic Columns
You need poor man's pivot:
Poor Man's SQL Pivot. List Questions as Columns and Answers per User in one row
Static Columns
For example:
select
AccountNo,
case when sum(case when ResourceNo = 134 then 1 else 0 end) = 0 then '' else 'X' end as Resource_134,
case when sum(case when ResourceNo = 115 then 1 else 0 end) = 0 then '' else 'X' end as Resource_115
from
AccountResource
group by
AccountNo
Example Data:
AccountNo ResourceNo ProductNo CustomerNo
A1 134 P1 C1
A1 134 P2 C1
A1 134 P3 C2
A2 134 P1 C1
A2 115 P1 C4
A2 115 P2 C1
A3 115 P5 C2
Example output:
AccountNo Resource_134 Resource_115
A1 X
A2 X X
A3 X
Dynamic Columns
For dynamic columns you can do this:
declare #sql nvarchar(max)
set #sql = ''
select #sql = #sql + ',' + char(13)+char(10)+
'case when sum(case when ResourceNo = ''' + replace(cast(ResourceNo as nvarchar(10)), '''', '''''') + ''' then 1 else 0 end) = 0 then '''' else ''X'' end as "Resource_' + replace(cast(ResourceNo as nvarchar(10)), '"', '""') + '"'
from AccountResource
group by ResourceNo
order by Resourceno
set #sql = 'select AccountNo' + #sql
+ char(13)+char(10)
+ 'From AccountResource '
+ char(13)+char(10)
+ 'group by AccountNo'
+ char(13)+char(10)
+ 'order by AccountNo'
select * from datacheck.dbo.splitmax(#sql, null,null)
exec sp_executesql #sql