获取sql server中两个日期之间的列的总和?

时间:2016-02-05 10:09:08

标签: sql-server count numeric

我有一张表:

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

我正在处理工资单报告,上表是离职表。现在,管理员希望在两个日期之间生成工资核算报告,例如2016年1月1日和#39;到2016年1月25日。它将为用户ID 1 获取3个计数。但是当管理员进入详细报告时,在这个peroid中还有2个叶子,即24,25 jan。

我使用了以下查询:

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

我们不想通过循环来做到这一点。我不想迭代循环,以了解从日期到结束日期之间的日期。有什么方法可以实现这个目标。请帮我。

更新 对不起,我的问题有点令人困惑:让我们再试一次:

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

即。

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

现在,当我的startdate = 2016年1月24日和Enddate =&#39; 2016年1月28日&#39; ..我的上述查询将返回的是:&#34; 7 &#34 ;.权利..

现在我正在追踪2016年1月25日&#34;的结束日期。现在我的查询将返回的是: 3 因为根据我的条件,它将仅获取日期小于通过(enddate即25-jan-2016)日期的记录。所以它只能获取 3

但是我希望得到 5 的结果,对于15-17 jan的日期表示3,对于24和25日的日期表示2。

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

3 个答案:

答案 0 :(得分:2)

如果我理解你想要的话:

  1. 表格中的一列,详细说明了其他两列之间的天数。
  2. 此列应始终反映最新数据。
  3. 您可以使用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。使用正确的数据类型存储日期允许您使用多个date and time functions的SQL,这简化了此任务。

    修改

    我误会了。 OP想要覆盖表中存储的结束日期。

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

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

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

    覆盖示例

    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
    ;
    

答案 1 :(得分:2)

这将在参数中描述的间隔中获得休假天数:

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

答案 2 :(得分:0)

我的解决方案:

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 

希望这也有助于......