计算SQL Server

时间:2016-05-28 04:41:07

标签: sql sql-server sql-server-2012

我的考勤数据列表如下所示。现在,我试图按特定日期范围(2016年5月1日 - 2016年5月7日)查找数据,总有效列,总有效列将根据以前的当前数据(P)计算。假设今天是2016年5月4日。如果一个人有01,02,03,04状态'p',那么它将显示04-05-2016总日期4。

enter image description here

你能帮我从这个结果集中找到总数吗?

3 个答案:

答案 0 :(得分:6)

您可以查看此示例,该示例具有计算先前总和值的逻辑。

declare @t table (employeeid int, datecol date, status varchar(2) )

insert into @t values (10001, '01-05-2016', 'P'),
(10001, '02-05-2016', 'P'),
(10001, '03-05-2016', 'P'),
(10001, '04-05-2016', 'P'),
(10001, '05-05-2016', 'A'),
(10001, '06-05-2016', 'P'),
(10001, '07-05-2016', 'P'),
(10001, '08-05-2016', 'L'),
(10002, '07-05-2016', 'P'),
(10002, '08-05-2016', 'L')

--select * from @t 

select * ,  
    SUM(case when status = 'P' then 1 else 0 end) OVER (PARTITION BY   employeeid ORDER BY employeeid, datecol
    ROWS BETWEEN UNBOUNDED PRECEDING 
      AND current row) 
from 
@t

通过cte的同一件事的另一个转折(正如您编写的SQLSERVER2012,此解决方案仅适用于Sqlserver 2012及更高版本)

;with cte as
(
    select  employeeid , datecol , ROW_NUMBER() over(partition by employeeid order by employeeid, datecol) rowno
    from 
    @t where status = 'P'
)
select t.*, cte.rowno , 
    case when ( isnull(cte.rowno, 0) = 0) 
    then LAG(cte.rowno) OVER (ORDER BY t.employeeid, t.datecol) 
    else cte.rowno
    end LagValue 
from @t t left join cte on t.employeeid = cte.employeeid and t.datecol = cte.datecol
order by t.employeeid, t.datecol

答案 1 :(得分:2)

您可以使用子查询为每行计算TotalPresent

SELECT 
    main.EmployeeID, 
    main.[Date], 
    main.[Status], 
    (
        SELECT SUM(CASE WHEN t.[Status] = 'P' THEN 1 ELSE 0 END) 
        FROM [TableName] t
        WHERE t.EmployeeID = main.EmployeeID AND t.[Date] <= main.[Date]
    ) as TotalPresent
FROM [TableName] main
ORDER BY 
    main.EmployeeID, 
    main.[Date]

这里我使用子查询来计算具有相同EmployeeID且日期小于或等于当前行日期的记录总和。如果记录的状态为&#39; P&#39;,则将1添加到总和,否则为0,它仅计算具有状态P的记录。

答案 2 :(得分:2)

有趣的问题,这应该有效:

select *
, (select count(retail) from p g 
   where g.date <= p.date and g.id = p.id and retail = 'P')
from p
order by ID, Date;

所以我相信我理解正确。您希望按日期计算每个ID的出现次数。

这很有道理。这就是为什么ID2的第一次出现是L而且Total是0.这个查询将计算每次出现的P状态,对于每个ID暂停非P..

Here is an example