获取 sql 服务器中两个日期之间的列的总和?

Get sum of a column between two dates in sql server?

我有一个 table 喜欢 :

EmpId , LeaveDays, StartDate,       EndDate
------------------------------------------------------
1    , 4        , 24-Jan-2016,     27-Jan-2016
2    , 4        , 26-Jan-2016,     29-Jan-2016
1    , 3        , 15-Jan-2016,     17-Jan-2016

我正在处理工资单报告,table 以上请假table。现在管理员想要在“2016 年 1 月 1 日”到 2016 年 1 月 25 日这两个日期之间生成工资单报告。它将为 ID 为 1 的用户获取 3 个计数。但是当管理员查看详细报告时,这个周期还有 2 个叶子,即 1 月 24 日、25 日。

我使用了以下查询:

select ISNULL(sum(convert(float,NumberOfDays)),0) from table
    WHERE FromDate >= '15-Jan-2016' and EndDate <='25-Jan-2016'

我们不想循环执行此操作。我不想迭代循环以获取介于 fromdate 和 Enddate 之间的日期数。有什么办法可以实现这个目标。请帮我。

更新: 对不起,我的问题有点混乱:让我们再解释一下:

我们有两条 empId=1 的记录好吗?

EmpId , LeaveDays, StartDate,       EndDate
------------------------------------------------------
1    , 4        , 24-Jan-2016,     27-Jan-2016
1    , 3        , 15-Jan-2016,     17-Jan-2016

现在当我的开始日期 = 24-Jan-2016 和结束日期 ='28-Jan-2016'.. 我上面的查询 return 是:“7”。对..

现在我将结束日期链接到“2016 年 1 月 25 日”。现在我的查询 return 是:3 因为根据我的条件,它将只获取日期小于通过(结束日期,即 2016 年 1 月 25 日)日期的记录。所以它只会获取 3

但我想得到 5 的结果,意味着 1 月 15-17 日为 3,1 月 24 日和 25 日为 2。

我希望我的问题现在很清楚了..:)

如果我没听错你想要:

  1. 您 table 中的一列,详细说明其他两列之间的天数。
  2. 此列应始终反映最新数据。

您可以使用 Computed Column 实现此目的。这些是虚拟列,其内容是按需计算的。

例子

CREATE TABLE #Example
    (
        Id              INT,
        StartDate       DATE,
        EndDate         DATE,

        NumberOfDays    AS DATEDIFF(DAY, StartDate, EndDate)
    )
;

/* Only start and end dates need adding, 
 * the number of days is calcualted.
 */
INSERT INTO #Example
    (
        Id,
        StartDate,
        EndDate
    )
VALUES
    (1, '2015-12-01', '2015-12-31'),
    (2, '2015-12-02', '2015-12-28')
;


-- Let's see what we have.
SELECT
    *
FROM
    #Example
;

结果

Id  StartDate    EndDate     NumberOfDays
1   2015-12-01   2015-12-31  30
2   2015-12-02   2015-12-28  26

您似乎将日期存储在文本列中。在我的例子中,我有 date data type. Storing dates using the correct data type allows you to make use of SQLs many date and time functions,它简化了这个任务。

编辑

我误会了。 OP 想要覆盖存储在 table.

中的结束日期

此查询计算起点和终点之间的天数,替换超过设定日期的任何终点。

为此,我使用了 CASE expression,它取代了给定范围之外的结束日期。我还在结果中加了 1。如果没有这个,我们将计算两天之间的差异,而不是包含的天数。

我再次将文本日期替换为日期日期,因此我可以利用 SQL 服务器丰富的日期功能。

覆盖示例

DECLARE @EndDate    DATE = '2016-01-25';

WITH Emp AS
    (
        /* CTE returns sample data for us to 
         * experiment with.
         */
        SELECT
            r.*
        FROM
            (
                VALUES
                    (1, 4, '2016-01-24', '2016-01-27'),
                    (1, 3, '2016-01-15', '2016-01-17')
            ) AS r(EmpId, LeaveDays, StartDate, EndDate)
    )
/* Returns the number of days between the start and end date.
 * If the end date exceeds a set limit this is used instead.
 */
SELECT
    EmpId,
    SUM(
        DATEDIFF(
            DAY,
            StartDate,
            CASE WHEN EndDate > @EndDate THEN @EndDate ELSE EndDate END
        ) + 1
    ) AS LeaveDays
FROM
    Emp
GROUP BY
    EmpId
;

这将获取参数中描述的间隔内的休假天数:

DECLARE @t table
(EmpId int, LeaveDays int, StartDate date,       EndDate date)
INSERT @t values
(1    , 4        , '24-Jan-2016',     '27-Jan-2016'),
(2    , 4        , '26-Jan-2016',     '29-Jan-2016'),
(1    , 3        , '15-Jan-2016',     '17-Jan-2016')

DECLARE @StartDate date = '14-Jan-2016' , @EndDate date= '25-Jan-2016'

-- adding 1 to include both days

SELECT 
  DATEDIFF(day, 
    CASE WHEN @StartDate < StartDate THEN StartDate ELSE @StartDate END,
    CASE WHEN @EndDate < EndDate THEN @EndDate ELSE EndDate END) +1
      LeaveDaysWithinInterval, 
  *
FROM @t
WHERE StartDate <= @EndDate
and @StartDate <= EndDate

结果:

LeaveDaysWithinInterval  EmpId  LeaveDays  StartDate   EndDate
2                        1      4          2016-01-24  2016-01-27
3                        1      3          2016-01-15  2016-01-17

我的解决方案:

declare @stdate datetime, @eddate datetime, @emp_cur cursor,@empid int
set @stdate = '2011-11-01 00:00:00.000'
set @eddate = '2011-11-30 00:00:00.000'


create table #temp(emp_id int,no_days int, st_date datetime,ed_date datetime)
insert into #temp
select employee_id, no_of_days,StartDate,EndDate from LeaveDays
where ( StartDate between @stdate and @eddate) or (EndDate between @stdate and @eddate) 

create table #temp1 (emp_id1 int, no_days1 int)
set @emp_cur= cursor scroll  for select emp_id from #temp
open @emp_cur
    fetch next from @emp_cur into @empid
    while(@@fetch_status = 0)
        begin
            insert into #temp1
            select emp_id, sum(no_days) - 
            ((select isnull(sum(datediff(day,st_date,@stdate)),0) from #temp where emp_id =@empid and st_date not between @stdate and @eddate) + 
            (select isnull(sum(datediff(day,@eddate,ed_date)),0) from #temp where emp_id =@empid and ed_date not between @stdate and @eddate)) from #temp where emp_id=@empid group by emp_id 
            fetch next from @emp_cur into @empid
        end
    close @emp_cur
deallocate @emp_cur
select distinct * from #temp1 order by emp_id1

drop Table #temp
drop Table #temp1 

希望这也有助于...