0

私は非常に簡単なデータ検証用のストアド プロシージャを作成しています。実行したいいくつかのSQLステートメントがあり、ソースと比較するために結果を表示するだけです。SQL ステートメントをユニオンで結合しましたが、異なるデータ型の列を結合することはできません。うまくいけば、誰かがより良い進め方について提案をしてくれるでしょうか?

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

いくつかの変更点に注意してください:

  • すべてのエイリアスを削除しました-とにかく、ユニオンの最初のステートメントの後は無視されます。
  • 2番目の列に対して明示的な変換を使用して、うまくいけば互換性のあるデータ型に変換します。
  • すべてのキーワード (例: 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 に答える