从两个表将行转换为列

时间:2014-06-02 06:48:25

标签: sql sql-server sql-server-2008

我正在尝试查询考勤数据库,该数据库显示来自两个表的以下数据

USERINFO
USERID   Name
1    Joe Bloggs

CHECKINOUT
USERID   CHECKTIME
1    27/05/2014 07:44
1    27/05/2014 13:50
1    28/05/2014 08:12
1    28/05/2014 16:27
1    29/05/2014 07:46
1    29/05/2014 16:30
1    30/05/2014 07:40
1    30/05/2014 15:59


Select dbo.USERINFO.NAME, dbo.CHECKINOUT.CHECKTIME 
FROM dbo.USERINFO Inner Join dbo.CHECKINOUT on dbo.USERINFO.USERID = dbo.CHECKINOUT.USERID
Query results:
Name    CheckTime
Joe Bloggs  27/05/2014 07:44
Joe Bloggs  27/05/2014 13:50
Joe Bloggs  28/05/2014 08:12
Joe Bloggs  28/05/2014 16:27
Joe Bloggs  29/05/2014 07:46
Joe Bloggs  29/05/2014 16:30
Joe Bloggs  30/05/2014 07:40
Joe Bloggs  30/05/2014 15:59

我想看到的是这样的:

Name    CheckTime   ClockIn ClockOut
Joe Bloggs  27/05/2014  07:44:55    13:50:53
Joe Bloggs  28/05/2014  08:12:03    16:27:10
Joe Bloggs  29/05/2014  07:46:59    16:30:06
Joe Bloggs  30/05/2014  07:40:23    15:59:41

我尝试了将此行中的行转换为列的所有建议,但我无法使其工作。

编辑: 基本上我尝试了PIVOT,XML方法,CASE语句和COALESCE函数,但是我遇到了很多错误。我是SQL Server的新手,但在MSAccess中完成了PIVOT。

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:1)

以下代码会给你这样的东西,希望这就是你想要的

名称 | ClockIn | ClockOut
Joe Bloggs | 2014-05-27 07:44:00.000 | 2014-05-27 13:50:00.000
Joe Bloggs | 2014-05-28 08:12:00.000 | 2014-05-28 16:27:00.000
Joe Bloggs | 2014-05-29 07:46:00.000 | 2014-05-29 16:30:00.000
Joe Bloggs | 2014-05-30 07:40:00.000 | 2014-05-30 15:59:00.000

    CREATE TABLE #PRERESULT(
    Name nvarchar(50),
    CheckTime datetime)

    INSERT INTO #PRERESULT
    VALUES
    ('Joe Bloggs',  '2014-05-27 07:44'),
    ('Joe Bloggs',  '2014-05-27 13:50'),
    ('Joe Bloggs',  '2014-05-28 08:12'),
    ('Joe Bloggs',  '2014-05-28 16:27'),
    ('Joe Bloggs',  '2014-05-29 07:46'),
    ('Joe Bloggs',  '2014-05-29 16:30'),
    ('Joe Bloggs',  '2014-05-30 07:40'),
    ('Joe Bloggs',  '2014-05-30 15:59')


    CREATE TABLE #RESULT(
    name nvarchar(50),
    ClockIn datetime,
    ClockOut datetime)


    DECLARE @Day nvarchar(50)

    DECLARE C_Checktime CURSOR
    FOR

    SELECT DISTINCT FORMAT(Checktime,'dd/MM/yyyy') as Checktime
    FROM #PRERESULT 

    OPEN C_Checktime

    FETCH NEXT FROM C_Checktime INTO @Day
    While (@@Fetch_status = 0)
    BEGIN

    INSERT INTO #RESULT
    SELECT a.name
    , b.CheckTime As ClockIn
    , a.CheckTime As ClockOut
    FROM #PRERESULT a JOIN #PRERESULT b 
    ON a.CheckTime > b.Checktime
    WHERE FORMAT(a.Checktime,'dd/MM/yyyy') = @Day
    AND FORMAT(b.Checktime,'dd/MM/yyyy') = @Day
    AND a.CheckTime <> b.CheckTime 

    FETCH NEXT FROM C_Checktime INTO @Day
    END

    CLOSE C_Checktime
    DEALLOCATE C_Checktime

    SELECT * FROM #RESULT

    DROP TABLE #PRERESULT
    DROP TABLE #RESULT

将您的日期时间格式转换为我的使用:

SELECT convert(datetime, Checkdate, 103)

希望这能帮助你,度过美好的一天

艾蒂安

答案 1 :(得分:1)

您不需要PIVOTXML之类的内容,只需按日期分组

SELECT UserID
     , DateAdd(dd, DateDiff(dd, 0, CHECKTIME), 0) CheckTime
     , CONVERT(VARCHAR(8), Min(CHECKTIME),108) ClockIn 
     , CONVERT(VARCHAR(8), Max(CHECKTIME),108) ClockOut
FROM   CHECKINOUT
GROUP BY UserID, DateAdd(dd, DateDiff(dd, 0, CHECKTIME), 0)

SQLFiddle demo