【问题标题】:SQL Server calculate days from current date excluding days from another tableSQL Server 从当前日期计算天数,不包括另一个表中的天数
【发布时间】:2018-06-18 15:35:11
【问题描述】:

我正在尝试编写一个允许我获取下表的查询:

| Username | Startdate | Points |
|----------|-----------|--------|
| XXY      | 15-03-18  |      0 |
| YYX      | 12-02-18  |      1 |
| ZZY      | 10-06-18  |      2 |

并计算从当天开始的天数,不包括表 2 中用户缺席的天数。

| Username | Startdate | Enddate  |
|----------|-----------|----------|
| XXY      | 20-03-18  | 25-03-18 |

还有一个问题,我需要两个表在当前日期之前的每一天都有一行。我该怎么做?

更新:我在表 1 DATEDIFF(DAY, Startdate,GETDATE()) 中尝试过这个,这给了我天数。但我需要从中减去 5 天(见表 2)

【问题讨论】:

  • 你能举一个你目前厌倦的代码示例吗?
  • 嗨,Tomos,我添加了更多信息
  • 无意冒犯,但该数据和结果非常令人困惑。它们似乎无关。 Username: XXYStartdate: 15-03-18 变为 Startdate: 02-03-18。这里有什么关系?另外,在您的结果情况下,您假设的计算字段会是什么样子?

标签: sql-server date


【解决方案1】:
select 
datediff(day, table1.StartDate, getdate()) - datediff(day, table2.StartDate, table2.Enddate)
from table1 
join table2 on table1.Username = table2.Username

【讨论】:

    【解决方案2】:

    一种方法是执行以下操作:

    USE Sandbox;
    GO
    
    CREATE TABLE Dates (SkipDate date);
    GO
    
    INSERT INTO Dates
    VALUES ('20180605'),('20180617');
    GO
    
    WITH VTE AS (
        SELECT CONVERT(date,S) StartDate, CONVERT(date, E) EndDate
        FROM (VALUES('20180601','20180606'),
                    ('20180601','20180618')) V(S,E))
    SELECT StartDate,
           EndDate,
           DATEDIFF(DAY, StartDate, EndDate) AS DaysBetween,
           DATEDIFF(DAY, StartDate, EndDate) - SkipDates AS DaysMinusSkipped
    FROM VTE
         CROSS APPLY (SELECT COUNT(*) AS SkipDates
                      FROM Dates
                      WHERE SkipDate >= StartDate
                        AND SkipDate <= EndDate) AS SD;
    GO
    

    如果您想创建一些不需要每次都编写该 SQL 的东西,您可以创建一个表值函数:

    CREATE FUNCTION dbo.DateDiffSkip (@StartDate date, @EndDate date)
    RETURNS TABLE
    AS RETURN
    
        SELECT DATEDIFF(DAY, @StartDate, @EndDate) - COUNT(SkipDate) AS DateDiffSkip
        FROM Dates D
        WHERE D.SkipDate >= @StartDate
          AND D.SkipDate <=  @EndDate;
    
    GO
    

    那么,您的 SQL 将是:

    WITH VTE AS (
        SELECT CONVERT(date,S) StartDate, CONVERT(date, E) EndDate
        FROM (VALUES('20180601','20180606'),
                    ('20180601','20180618')) V(S,E))
    SELECT StartDate,
           EndDate,
           DATEDIFF(DAY, StartDate, EndDate) AS DaysBetween,
           DDS.DateDiffSkip AS DaysMinusSkipped
    FROM VTE
         CROSS APPLY dbo.DateDiffSkip(StartDate, EndDate) DDS;
    GO
    --Clean up
    DROP FUNCTION DateDiffSkip;
    DROP TABLE Dates;
    

    【讨论】:

      【解决方案3】:

      这可以使用多个 DATEDIFF 函数来计算。这也计算每个用户的多次缺勤:

      declare @t table ([UserName] char(3), [StartDate] Date, [Points] int)
      insert into @t values ('XXY', '2018-03-15', 0), ('YYX', '2018-02-12', 1), ('ZZY', '2018-06-10', 2)
      
      declare @a table ([UserName] char(3), [StartDate] Date, [EndDate] Date)
      insert into @a values ('XXY', '2018-03-20', '2018-03-25')
      
      select t.*, datediff(d, t.[StartDate], cast(getdate() as date)) - isnull(sum(datediff(d, a.[StartDate], a.[EndDate])), 0) as [DaysNotAbsent]
      from @t t
      left join @a a on t.UserName = a.UserName
      group by t.UserName, t.StartDate, t.Points
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-25
        • 2012-07-08
        • 2019-04-15
        • 1970-01-01
        相关资源
        最近更新 更多