SQL使用as范围选择LAG和LEAD之间的项目

时间:2017-09-02 15:55:53

标签: sql sql-server tsql lag lead

是否可以使用Lag和来自另一个表格的表格从表格中选择和求和,如下所示。

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 Age Categories。我需要总列数在范围内准确。

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

1 个答案:

答案 0 :(得分: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语句复杂化效率更高一些。它也使它更具可读性。

感谢HABO对GetDate()的建议