0

我正在为数据验证创建一个非常简单的存储过程。我有几个我希望运行的 sql 语句并简单地显示结果以与源进行比较。我将 sql 语句与 union 组合在一起,但您不能将不同数据类型的列联合在一起。希望有人会对更好的方法提出建议吗?

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'

我想看到如下结果:

总工资总和:50000000
总体平均工资:37000
员工姓名 - 1:
2012 年第一个最后一个个人员工经验:12

4

1 回答 1

1

为什么不横向翻转,这样您就不必使用联合,您只需横向扫描数据:

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;

不确定您是否真的要进行硬编码'first''last'但我怀疑这些作为参数会更好,特别是如果您要多次引用它们。

鉴于您的要求是由 Excel 驱动的,也许可以尝试:

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';

注意一些变化:

  • 删除了所有别名-无论如何,在联合中的第一条语句之后它们都会被忽略。
  • 使用显式将第二列转换为希望兼容的数据类型。
  • 正确地将所有关键字(例如year)括在方括号中。删除了那些不必要的——它们只会使查询更难阅读。
  • 创建了 year 参数的字符串版本,以便可以将其附加到第一列而无需执行任何转换。

现在,你已经把问题简化了,还有更多我们看不到的查询。但我仍然认为更好的方法是放弃对基表的联合并以这种方式执行它(特别是如果您对同一个表有 10 或 15 个以上的查询)。这不一定会执行任何不同的操作,但维护起来会容易得多

;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;

除此之外,我认为您的方法首先非常麻烦。您真的是通过将这些查询拼凑在一起并将结果手动粘贴到 Excel 中来执行数据验证吗?当然有一种更自动化的方法可以做到这一点,而不是尝试定制笨拙的 SQL 查询以符合您的流程,您应该改进流程......

于 2013-01-16T18:34:28.200 回答