2017-09-02 57 views
1

是否可以使用延遲和從另一個表作爲範圍來選擇和彙總項目,如下所示。SQL選擇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」,生成下面一個臨時表,使用funtion分裂

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

希望它現在有點清晰。 – Prince

回答

2

東西沿着這些線路應爲你工作:

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 

結果集是這樣的:

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

以供將來參考,特別是問SQL的問題時,你會得到遠如果您提供我已完成的大部分工作,則可以更快更好地做出迴應。即爲有關表格創建語句並插入語句以提供示例數據。你做這件事比我們要容易得多(我們必須複製和粘貼,然後重新格式化等),而你應該可以通過幾個選擇SELECT語句來做同樣的事情!

請注意,我處理的情況下,當出生日期超出給定的範圍,而不同。通過MAX進行一次單一檢查比使SELECT語句複雜化要有效得多。它也使它更可讀。

由於哈勃的建議上GETDATE()

+0

謝謝,它的工作設法適合我的商店程序。 – Prince

+0

也感謝您的建議。 – Prince

+0

提示:查詢中'GetDate()'有點奇怪。每個_instance_在查詢中都有一個常量值。例如'select D1(GetDate(),GetDate()as SomeTable'中的D2可能爲兩列返回兩個不同的值,但它們不會因行而變化。當在多個語句中使用'GetDate()'時,例如在存儲過程中,可以通過獲取單個值並在整個過程中使用它,即'declare @Now as DateTime = GetDate();'並根據需要使用'@ Now'來避免有趣的意外。 – HABO