Reputation: 783
I'm creating a stored procedure for data validation that is pretty straight forward. I have several sql statements that i wish to run and simply display the results to compare to the source. I combined the sql statements with a union but you can not union together columns of different data types. Hopefully someone will have a suggestion on a better way to proceed?
USE [employee_data]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[data_employee]
AS
BEGIN
declare @LtYear as varchar(10)
set @LtYear = '2012'
SELECT 'Sum of total salary for ' + @LtYear as title, sum([Total_Salary]) as Salary
From [employee_data].[dbo].[employee]
where year = @LtYear
UNION
select 'Overall Average Salary ' + @LatestYear as title, avg([Total_Salary]) as 'Average Salary'
From [employee_data].[dbo].[employee]
where year = @LtYear
SELECT 'Employee Name - 1' as title, first_name+' '+last_name
From [employee_data].[dbo].[employee]
where year = 2012 --@LtYear
and [First_Name] = 'first'
and [Last_Name] = 'last'
UNION
SELECT 'Individual Employee Experience ' + @LtYear as title, cast([work_Exp]as varchar) as 'Work Experience'
From [employee_data].[dbo].[employee]
where year = @LtYear
and [First_Name] = 'first'
and [Last_Name] = 'last'
I would like to see the results as follows:
Sum of Total Salary: 50000000
Overall Average Salary: 37000
Employee Name - 1: First Last
Individual Employee Experience 2012: 12
Upvotes: 0
Views: 12177
Reputation:
Why not do this flipped sideways so that you don't have to use unions, you just have to scan the data sideways:
SELECT [Year] = @LtYear,
[Sum of Total Salary] = s.s,
[Average Salary] = s.a,
[Employee Name] = e.first_name + ' ' + e.last_name,
[Work Experience] = CONVERT(VARCHAR(12), e.work_Exp
FROM employee_data.dbo.employee AS e
CROSS JOIN
(
SELECT SUM(Total_Salary), AVG(Total_Salary)
FROM employee_data.dbo.employee
WHERE [Year] = @LtYear
) AS s(s,a)
WHERE e.[Year] = @LtYear
AND e.First_Name = @first_name
AND e.Last_Name = @last_name;
Not sure if you really meant to hard-code 'first'
and 'last'
but I suspect those would be better as parameters, especially if you're going to reference them multiple times.
Given that your requirements are driven by Excel, maybe try:
DECLARE @y CHAR(4);
SET @y = CONVERT(CHAR(4), @LtYear);
SELECT col1 = 'Sum of total salary for ' + @y,
col2 = CONVERT(NVARCHAR(255), sum(Total_Salary) as Salary)
From employee_data.dbo.employee
where [year] = @LtYear
UNION ALL
SELECT 'Overall Average Salary ' + @y,
CONVERT(NVARCHAR(255), avg(Total_Salary))
From employee_data.dbo.employee
where [year] = @LtYear
UNION ALL
SELECT 'Employee Name - 1',
CONVERT(NVARCHAR(255), first_name+' '+last_name)
From employee_data.dbo.employee
where [year] = @LtYear
and First_Name = 'first'
and Last_Name = 'last'
UNION ALL
SELECT 'Individual Employee Experience ' + @y,
CONVERT(NVARCHAR(255), work_Exp)
From employee_data.dbo.employee
where [year] = @LtYear
and First_Name = 'first'
and Last_Name = 'last';
Notice a few changes:
year
) in square brackets. Removed those that aren't necessary - they only serve to make the query harder to read.Now, you've dumbed down the question, and there are more queries that we can't see. But I still think a better approach would be to ditch the unions against the base table and perform it this way instead (especially if you have 10 or 15 more queries against the same table). This isn't necessarily going to perform any differently, but it will be a lot easier to maintain.
;WITH x AS
(
SELECT
y = CONVERT(CHAR(4), @LtYear),
[ss] = CONVERT(NVARCHAR(255), s.s),
[as] = CONVERT(NVARCHAR(255), s.a),
[en] = CONVERT(NVARCHAR(255), e.first_name + ' ' + e.last_name),
[we] = CONVERT(NVARCHAR(255), e.work_Exp)
FROM employee_data.dbo.employee AS e
CROSS JOIN
(
SELECT SUM(Total_Salary), AVG(Total_Salary)
FROM employee_data.dbo.employee
WHERE [Year] = @LtYear
) AS s(s,a)
WHERE e.[Year] = @LtYear
AND e.First_Name = @first_name
AND e.Last_Name = @last_name
)
SELECT 'Sum of total salary for ' + y, [ss] FROM x
UNION ALL
SELECT 'Overall average salary for ' + y, [as] FROM x
UNION ALL
SELECT 'Employee Name - 1', [en] FROM x
UNION ALL
SELECT 'Individual Employee Experience ' + y, [we] FROM x;
Further to that, I think your approach is very troublesome in the first place. You're really performing data validation by cobbling these queries together and manually pasting the results into Excel? Surely there is a more automated way to do this, and instead of trying to tailor an unwieldy SQL query to conform to your process, you should improve the process...
Upvotes: 1