-1

我的出勤表中有以下数据:

Staff_ID  |       User_Attend_Date    |  Business_Day 
  S01     |   2013-05-01 15:18:45.537 |   2013-05-01  
  S01     |   2013-05-02 00:00:00.000 |   2013-05-01  
  S02     |   2013-05-03 06:20:30.225 |   2013-05-02  

我想显示一个新列来检查员工入住日期减去 3 小时是否与工作日相同。如果与工作日相同,则保留 User_Attend_Date。我的 Business_Day 数据类型是 DATE,其他 2 列是 DATETIME。结果应如下所示:

 Staff_ID  |       User_Attend_Date    |  Business_Day   |     Check_Same_Day
   S01     |   2013-05-01 15:18:45.537 |   2013-05-01    | 2013-05-01 15:18:45.537
   S01     |   2013-05-02 00:00:00.000 |   2013-05-01    | 2013-05-01 15:18:45.537
   S02     |   2013-05-03 06:20:30.225 |   2013-05-02    | 2013-05-03 06:20:30.225

我尝试了以下代码,但未能达到结果。

SELECT *, Case WHEN DATEADD(hh, -3, User_Attend_Date)=Business_Day 
THEN User_Attend_Date ELSE BusinessDay END As 'Check_Same_Day' FROM tblAttendance

我尝试在分区上使用,但也失败了。

DATEADD(hh, -3, User_Attend_Date) OVER (PARTITION BY BusinessDay) AS 'Check_Same_Day'

希望有人能教我。谢谢

4

6 回答 6

2

要将日期时间更改为它所在的日期,请使用:

SELECT DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0), GETDATE()

所以在你的情况下,你可以用它来比较Business_Day

SELECT Case WHEN DATEADD(d, DATEDIFF(d, 0, DATEADD(hour, -3, User_Attend_Date)), 0) = Business_Day

编辑

您实际上希望在任何一天为用户使用第一次登录,因此您可以使用 CTE 来实现此目的。我添加了一个“期望”列(您可以轻松删除),我假设您也必须有一个 user_id 来识别用户?如果是这样,请尝试:

http://sqlfiddle.com/#!3/c54b4/1

WITH AttendanceDate AS (
  SELECT User_Id, User_Attend_Date, Business_Day, DATEADD(d, DATEDIFF(d, 0, DATEADD(hour, -3, User_Attend_Date)), 0) AS ActualAttendDate
  FROM tblAttendance ),
FirstAttendance AS (
  SELECT User_Id, ActualAttendDate, MIN(User_Attend_Date) FirstLogin
  FROM AttendanceDate
  GROUP BY User_Id, ActualAttendDate
)
SELECT TA.User_Id, TA.User_Attend_Date, TA.Business_Day, FA.FirstLogin
FROM AttendanceDate AS TA
INNER JOIN FirstAttendance AS FA
    ON TA.User_Id = FA.User_Id
    AND TA.ActualAttendDate = FA.ActualAttendDate

请注意,演员表现在有点多余:http ://sqlfiddle.com/#!3/c54b4/2 ,并且要与多个用户一起查看:http ://sqlfiddle.com/#!3/4f2c7/1 。最终结果,没有Expect列在http://sqlfiddle.com/#!3/e9e6c/1上。

编辑 2

如果您不需要 User_Id 分组,那么它就像(http://sqlfiddle.com/#!3/0daab/1)一样简单:

WITH AttendanceDate AS (
  SELECT User_Attend_Date, Business_Day, DATEADD(d, DATEDIFF(d, 0, DATEADD(hour, -3, User_Attend_Date)), 0) AS ActualAttendDate
  FROM tblAttendance ),
FirstAttendance AS (
  SELECT ActualAttendDate, MIN(User_Attend_Date) FirstLogin
  FROM AttendanceDate
  GROUP BY ActualAttendDate
)
SELECT TA.User_Attend_Date, TA.Business_Day, FA.FirstLogin
FROM AttendanceDate AS TA
INNER JOIN FirstAttendance AS FA
    ON TA.ActualAttendDate = FA.ActualAttendDate

原始答案(根据解释预期结果如何组合的新信息不再相关)

完整(http://sqlfiddle.com/#!3/fa5bb/10):

SELECT User_Attend_Date, DATEADD(hour, -3, User_Attend_Date),
DATEADD(d, DATEDIFF(d, 0, DATEADD(hour, -3, User_Attend_Date)), 0) AS 'ForClarity1',
CAST(DATEADD(d, DATEDIFF(d, 0, DATEADD(hour, -3, User_Attend_Date)), 0) AS DATE) AS 'ForClarity2',
Business_Day AS 'ForClarity3',
 Case WHEN 
CAST(DATEADD(d, DATEDIFF(d, 0, DATEADD(hour, -3, User_Attend_Date)), 0) AS DATE) = Business_Day
 THEN User_Attend_Date ELSE Business_Day END As 'Check_Same_Day' 
FROM dbo.tblAttendance
于 2013-06-04T05:08:12.450 回答
0

您需要将第一列(日期时间)转换为日期以与日期进行比较。

 SELECT 
      *,
      CASE WHEN  CAST(DATEADD(HOUR,-4,User_Attend_Date) AS DATE)=Business_Day
        THEN User_Attend_Date 
        ELSE Business_Day 
      END AS Check_Same_Day
      FROM #test
于 2013-06-04T05:12:23.213 回答
0
SELECT USER_ATTEND_DATE,SUBSTRING(CAST(BUSINESS_DAY AS VARCHAR(20)),0,13)AS BUSINESS_DAY,

        案子
            WHEN DATEADD(hh, -3, User_Attend_Date) = Business_Day
            THEN Business_Day
            ELSE DATEADD(hh, -3, User_Attend_Date)
        END CHECK_SAME_DAY
从出席
于 2013-06-04T06:58:46.910 回答
0

我看到两个选项:

1)日期差异:

SELECT Case WHEN datediff(day,DATEADD(hh, -3, User_Attend_Date),Business_Day) < 1
THEN User_Attend_Date ELSE BusinessDay END As 'Check_Same_Day' FROM tblAttendance

2)演员:

SELECT Case WHEN Cast(DATEADD(hh, -3, User_Attend_Date) as Date) = Business_Day
THEN User_Attend_Date ELSE BusinessDay END As 'Check_Same_Day' FROM tblAttendance
于 2013-06-04T05:09:17.440 回答
0

您快到了,问题是您需要将 DATEADD 的结果转换为 DATE(而不是 DATETIME):

DECLARE @att TABLE
(
    User_Attend_Date DATETIME,
    Business_Day DATE
)

INSERT INTO @att
SELECT '2013-05-01 15:18:45.537', '2013-05-01'
UNION ALL
SELECT '2013-05-02 00:00:00.000', '2013-05-01'
UNION ALL
SELECT '2013-05-03 06:20:30.225', '2013-05-02'

SELECT 
    User_Attend_Date,
    Business_Day,
    CASE 
        WHEN CAST(DATEADD(hh, -3, User_Attend_Date) AS DATE) = Business_Day THEN User_Attend_Date
        ELSE Business_Day
    END AS 'Check_Same_Day'
FROM @att

这给出了您想要的结果,表明其中两个项目符合您的规则。

于 2013-06-04T05:09:23.373 回答
0

我认为它在行中显示秒值,因为您有数据类型 DATE 用于 Bussiness_day 和数据类型 DATETIME 用于其他列。

那么可以在 sql 2008 中使用 DATE 数据类型吗?

于 2013-06-04T05:47:53.917 回答