2017-09-02 2 views
1

Lagを使用してテーブルから項目を選択して合計し、次のような範囲の別の表から鉛を選択できますか?LAGとLEADの間で項目を選択範囲として使用

SELECT @Last = MAX(ID) from [dbo].[#Temp] 
    select opl.Name as [Age Categories] , 
    (SELECT count([dbo].udfCalculateAge([BirthDate],GETDATE())) 
     FROM [dbo].[tblEmployeeDetail] ed 
     inner join [dbo].[tblEmployee] e 
     on ed.EmployeeID = e.ID 
     where convert(int,[dbo].udfCalculateAge(e.[BirthDate],GETDATE())) 
      between LAG(opl.Name) OVER (ORDER BY opl.id) 
       and (CASE opl.ID WHEN @Last THEN '100' ELSE opl.Name End) 
    ) as Total 
FROM [dbo].[#Temp] opl 

tblEmployeeは、従業員や出産

INSERT INTO @tblEmployees VALUES 
(1, 'A', 'A1', 'A', '1983/01/02'), 
(2, 'B', 'B1', 'BC', '1982/01/02'), 
(3, 'C', 'C1', 'JR2', '1982/10/11'), 
(4, 'V', 'V1', 'G', '1990/07/12'), 
(5, 'VV', 'VV1', 'J', '1992/06/02'), 
(6, 'R', 'A', 'D', '1982/05/15'), 
(7, 'C', 'Ma', 'C', '1984/09/29') 

のそれぞれの日付が含まれている次の表は、年齢に応じて作成された一時テーブルは、ユーザなどによる入力で「20; 30; 50; 60」を生成します一時テーブルの下、使用目的球は分割

select * FROM [dbo].[Split](';','20;30;50;60') 

一時テーブル

pn s 
1 20 
2 30 
3 50 
4 60 

以下のような出力が必要ですが、C#のデータテーブルで列の年齢カテゴリの名前を変更できます。列全体が正確である必要があります。

これらの線に沿って何かがあなたのために働く必要があります
Age Categories  Total 
up to 20   0 
21 - 30    2 
31 - 50    5 
51 - 60    0 
+0

は、私たちはあなたの問題 –

+0

を評価することができ、あなたのサンプルデータと予想される結果を表示してくださいのGetDateの提案のためのHABOへ

おかげで、それは今少し明確に願っています。 – Prince

答えて

2

:SQL質問をする場合は特に、あなたが遠くなります、今後の参考のため

Age Categories Total 
Up to 20 0 
21 - 30 2 
31 - 50 5 
51 - 60 0 

declare @tblEmployees table(
ID int,  
FirstNames varchar(20),  
Surname varchar(20),  
Initial varchar(3),  
BirthDate date) 

INSERT INTO @tblEmployees VALUES 
(1, 'A', 'A1', 'A', '1983/01/02'), 
(2, 'B', 'B1', 'BC', '1982/01/02'), 
(3, 'C', 'C1', 'JR2', '1982/10/11'), 
(4, 'V', 'V1', 'G', '1990/07/12'), 
(5, 'VV', 'VV1', 'J', '1992/06/02'), 
(6, 'R', 'A', 'D', '1982/05/15'), 
(7, 'C', 'Ma', 'C', '1984/09/29') 

declare @temp table 
(id int identity, 
age int) 

INSERT INTO @temp 
SELECT cast(item as int) FROM dbo.fnSplit(';','20;30;50;60') 

declare @today date = GetDate() 
declare @minBirthCutOff date = (SELECT DATEADD(yy, -MAX(age), @today) FROM @temp) 
declare @minBirth date = (SELECT Min(birthdate) from @tblEmployees) 
IF @minBirth < @minBirthCutOff 
    BEGIN 
     INSERT INTO @temp VALUES (100) 
    end 
SELECT COALESCE(CAST((LAG(t.age) OVER(ORDER BY t.age) + 1) as varchar(3)) 
+ ' - ','Up to ') 
     + CAST(t.age AS varchar(3)) AS [Age Categories], 
     COUNT(e.id) AS [Total] FROM @temp t 
LEFT JOIN 
(SELECT te.id, 
     te.age, 
     (SELECT MIN(age) FROM @temp t WHERE t.age > te.age) AS agebucket 
FROM (select id, 
     dbo.udfCalculateAge(birthdate,@today) age from @tblEmployees) te) e 
ON e.agebucket = t.age 
GROUP BY t.age ORDER BY t.age 

結果セットは次のようになります私がやった仕事の多くをあなたが提供すれば、より迅速でより良い応答を得ることができます。つまり、関係するテーブルのステートメントを作成し、サンプルデータを提供するステートメントを挿入します。いくつかの選択肢SELECTステートメントで同じことができるはずですが、私たちにとってはこれを行う方がはるかに簡単です(コピーして貼り付けてから再フォーマットする必要があります)!

また、生年月日が指定された範囲をはるかに超えている場合は、私が扱ったことにも注意してください。 SELECTステートメントを複雑にするよりも、MAXを使用して一度だけチェックを行うほうが少し効率的です。また、読みやすくすることもできます。 ()

+0

ありがとうございます、それは私の店の手順にそれを収まるように管理しました。 – Prince

+0

アドバイスをいただきありがとうございます。 – Prince

+0

ヒント: 'GetDate()'はクエリで少しばかり扱われます。各_instance_は、クエリ内で一定の値を持ちます。たとえば、 'select GetDate()はD1、GetDate()はD2から' SomeTable'で2つの異なる値を返すかもしれませんが、行ごとに変化しません。複数のステートメントで 'GetDate()'を使うとき、例えば。ストアドプロシージャ内では、単一の値を取得し、それを使用することによって、興味深い驚きを避けることができます。つまり、 'DateTime = GetDate();を宣言し、必要に応じて' @ Now'を使用します。 – HABO

関連する問題