我有一张表:
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。
我希望我的问题现在很清楚.. :)
答案 0 :(得分: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。使用正确的数据类型存储日期允许您使用多个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
希望这也有助于......