查看当天的表格

时间:2013-06-04 04:57:48

标签: sql sql-server-2008

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

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.My_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'

希望有人可以教我。谢谢

6 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我看到两个选项:

1)DateDiff:

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

答案 2 :(得分: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

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

答案 3 :(得分: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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

SELECT  USER_ATTEND_DATE,SUBSTRING(CAST(BUSINESS_DAY AS VARCHAR(20)),0,13)AS BUSINESS_DAY,

        CASE 
            WHEN  DATEADD(hh, -3, User_Attend_Date) = Business_Day 
            THEN Business_Day
            ELSE DATEADD(hh, -3, User_Attend_Date)
        END CHECK_SAME_DAY
FROM attendance