我正在制作一个简单的时间和超时系统。我有3对进/出。
emp_id td_id status timestamp remarks
35 1 in 2013-12-19 10:15:09 late
35 2 out 2013-12-19 12:00:23 example
35 3 in 2013-12-19 13:00:23
35 4 out 2013-12-19 16:01:47
35 5 in 2013-12-19 18:01:17
35 6 out 2013-12-19 22:01:07
35 7 in 2013-12-20 10:00:12
这是我的疑问:
SELECT a1.emp_id, a1.status, a1.timestamp, a2.status, a2.timestamp, a3.status, a3.timestamp, a4.status, a4.timestamp, a5.status, a5.timestamp, a6.status, a6.timestamp
FROM overallrec a1
LEFT JOIN overallrec a2 ON a2.emp_id = a1.emp_id
AND a2.status = 'out'
LEFT JOIN overallrec a3 ON a3.emp_id = a1.emp_id
AND a3.status = 'in'
AND a3.timestamp <> a1.timestamp
LEFT JOIN overallrec a4 ON a4.emp_id = a1.emp_id
AND a4.status = 'out'
AND a4.timestamp <> a2.timestamp
LEFT JOIN overallrec a5 ON a5.emp_id = a1.emp_id
AND a5.status = 'in'
AND a5.timestamp <> a3.timestamp
LEFT JOIN overallrec a6 ON a6.emp_id = a1.emp_id
AND a6.status = 'in'
AND a6.timestamp <> a4.timestamp
WHERE a1.status = 'in'
这是我的结果:
emp_id status timestamp status timestamp status timestamp status timestamp status timestamp status timestamp
35 in 2013-12-19 10:15:09 out 2013-12-19 12:00:23 in 2013-12-19 13:00:23 out 2013-12-19 16:01:47 in 2013-12-19 18:01:17 out 2013-12-19 22:01:07
35 in 2013-12-20 10:00:12 out 2013-12-19 12:00:23 in 2013-12-19 13:00:23 out 2013-12-19 16:01:47 in 2013-12-19 18:01:17 out 2013-12-19 22:01:07
请注意,第一个'in'时间戳值第2行是另一个日期,但是下一个状态时间戳很快就会重复上一个日期。我希望它仍然为空时显示null,而不是复制上一个日期的值。换句话说,它应该在日更改时生成另一行。
附加说明:当我在每个输入添加备注时,它将在表结果中连接。我希望它是这样的:
emp_id status timestamp status timestamp status timestamp status timestamp status timestamp status timestamp remarks
35 in 2013-12-19 10:15:09 out 2013-12-19 12:00:23 in 2013-12-19 13:00:23 out 2013-12-19 16:01:47 in 2013-12-19 18:01:17 out 2013-12-19 22:01:07 "Late, Example"
35 in 2013-12-20 10:00:12 null null null null null null null null null null "Straight time"
我的查询怎么办?或者如果没有查询,还有什么?
答案 0 :(得分:1)
您可以尝试在查询中添加group by
:
group by a1.emp_id, date(a1.timestamp), date(a2.timestamp), date(a3.timestamp),
date(a4.timestamp), date(a5.timestamp), date(a6.timestamp)
说实话,我会将整个查询作为条件聚合进行,其中“in”和“out”在一行上。这适用于一对,但不是三对。我不明白为什么你要一排三对。那些一天只有两双的员工呢?或谁有四对?
答案 1 :(得分:1)
更改了答案,我忘了按时间戳1订购,这是最终版本,将照顾多名员工:) sqlFiddle
SELECT T1.emp_id,T1.status1 as status1,T1.timestamp1 as timestamp1,
T1.status2 as status2,T1.timestamp2 as timestamp2,
T2.status1 as status3,T2.timestamp1 as timestamp3,
T2.status2 as status4,T2.timestamp2 as timestamp4,
T3.status1 as status5,T3.timestamp1 as timestamp5,
T3.status2 as status6,T3.timestamp2 as timestamp6
FROM
(SELECT * FROM
(SELECT IF(((@row+1)=4) OR (@prevEmpId<>a1.emp_id),@row:=1,@row:=@row+1) as row,a1.emp_id,a1.status as status1,a1.timestamp as timestamp1,
'out' as status2,
@prevEmpId:=a1.emp_id,
(SELECT min(timestamp) as timestamp2
FROM overallrec a2
WHERE a2.timestamp > a1.timestamp
AND a2.emp_id = a1.emp_id
AND a2.status = 'out') as timestamp2
FROM overallrec a1,(SELECT @row:=0,@prevEmpId:=0)r
WHERE a1.status = 'in'
ORDER BY a1.emp_id,timestamp1
)T100
WHERE row=1
)T1
LEFT JOIN
(SELECT * FROM
(SELECT IF(((@row+1)=4) OR (@prevEmpId<>a1.emp_id),@row:=1,@row:=@row+1) as row,a1.emp_id,a1.status as status1,a1.timestamp as timestamp1,
'out' as status2,
@prevEmpId:=a1.emp_id,
(SELECT min(timestamp) as timestamp2
FROM overallrec a2
WHERE a2.timestamp > a1.timestamp
AND a2.emp_id = a1.emp_id
AND a2.status = 'out') as timestamp2
FROM overallrec a1,(SELECT @row:=0,@prevEmpId:=0)r
WHERE a1.status = 'in'
ORDER BY a1.emp_id,timestamp1
)T200
WHERE row=2
)T2
ON T1.emp_id = T2.emp_id AND DATE_FORMAT(T2.timestamp1,'%Y-%m-%d') = DATE_FORMAT(T1.timestamp1,'%Y-%m-%d')
LEFT JOIN
(SELECT * FROM
(SELECT IF(((@row+1)=4) OR (@prevEmpId<>a1.emp_id),@row:=1,@row:=@row+1) as row,a1.emp_id,a1.status as status1,a1.timestamp as timestamp1,
'out' as status2,
@prevEmpId:=a1.emp_id,
(SELECT min(timestamp) as timestamp2
FROM overallrec a2
WHERE a2.timestamp > a1.timestamp
AND a2.emp_id = a1.emp_id
AND a2.status = 'out') as timestamp2
FROM overallrec a1,(SELECT @row:=0,@prevEmpId:=0)r
WHERE a1.status = 'in'
ORDER BY a1.emp_id,timestamp1
)T300
WHERE row=3
)T3
ON T1.emp_id = T3.emp_id AND DATE_FORMAT(T3.timestamp1,'%Y-%m-%d') = DATE_FORMAT(T1.timestamp1,'%Y-%m-%d')
但是,如果员工在一天内计时,然后在第二天退出,那么这个查询将无效,因为它正在使用同一天检查以便加入
OP请求一个视图,但是mySQL中的View不允许变量,所以我尝试编写一个不同的查询(不使用变量),例如这个(sqlFiddle)SELECT T4.emp_id,T4.status1,T4.timestamp1,T4.status2,T4.timestamp2,
T4.status3,T4.timestamp3,T4.status4,T4.timestamp4,T4.status5,T4.timestamp5,
'out' as status6,
(SELECT min(timestamp)
FROM overallrec a
WHERE a.timestamp > T4.timestamp5
AND a.emp_id = T4.emp_id
AND a.status = 'out') as timestamp6
FROM
(SELECT T3.emp_id,T3.status1,T3.timestamp1,T3.status2,T3.timestamp2,
T3.status3,T3.timestamp3,T3.status4,T3.timestamp4,
'in' as status5,
(SELECT min(timestamp)
FROM overallrec a
WHERE a.timestamp > T3.timestamp4
AND a.emp_id = T3.emp_id
AND a.status = 'in') as timestamp5
FROM
(SELECT T2.emp_id,T2.status1,T2.timestamp1,T2.status2,T2.timestamp2,
T2.status3,T2.timestamp3,
'out' as status4,
(SELECT min(timestamp)
FROM overallrec a
WHERE a.timestamp > T2.timestamp3
AND a.emp_id = T2.emp_id
AND a.status = 'out') as timestamp4
FROM
(SELECT T1.emp_id,T1.status1,T1.timestamp1,T1.status2,T1.timestamp2,
'in' as status3,
(SELECT min(timestamp)
FROM overallrec a
WHERE a.timestamp > T1.timestamp2
AND a.emp_id = T1.emp_id
AND a.status = 'in') as timestamp3
FROM
(SELECT a1.emp_id,a1.status as status1,a1.timestamp as timestamp1,
'out' as status2,
(SELECT min(timestamp) as timestamp2
FROM overallrec a2
WHERE a2.timestamp > a1.timestamp
AND a2.emp_id = a1.emp_id
AND a2.status = 'out') as timestamp2
FROM overallrec a1
WHERE a1.status = 'in'
AND NOT EXISTS (SELECT 1 FROM overallrec e
WHERE e.timestamp < a1.timestamp
AND e.emp_id = a1.emp_id
AND DATE_FORMAT(e.timestamp,'%Y-%m-%d') =
DATE_FORMAT(a1.timestamp,'%Y-%m-%d'))
)T1
)T2
)T3
)T4;
不幸的是,mySQL视图不允许子查询(子查询不能在视图的FROM子句中使用。) 但mySQL允许的是在视图之上创建视图,所以这里是创建的视图 (sqlFiddle)
CREATE VIEW T100 AS
SELECT a1.emp_id,a1.status as status1,a1.timestamp as timestamp1,
'out' as status2,
(SELECT min(timestamp) as timestamp2
FROM overallrec a2
WHERE a2.timestamp > a1.timestamp
AND a2.emp_id = a1.emp_id
AND a2.status = 'out') as timestamp2
FROM overallrec a1
WHERE a1.status = 'in'
AND NOT EXISTS (SELECT 1 FROM overallrec e
WHERE e.timestamp < a1.timestamp
AND e.emp_id = a1.emp_id
AND DATE_FORMAT(e.timestamp,'%Y-%m-%d') =
DATE_FORMAT(a1.timestamp,'%Y-%m-%d'));
CREATE VIEW T200 AS
SELECT T1.emp_id,T1.status1,T1.timestamp1,T1.status2,T1.timestamp2,
'in' as status3,
(SELECT min(timestamp)
FROM overallrec a
WHERE a.timestamp > T1.timestamp2
AND a.emp_id = T1.emp_id
AND a.status = 'in') as timestamp3
FROM T100 AS T1;
CREATE VIEW T300 AS
SELECT T2.emp_id,T2.status1,T2.timestamp1,T2.status2,T2.timestamp2,
T2.status3,T2.timestamp3,
'out' as status4,
(SELECT min(timestamp)
FROM overallrec a
WHERE a.timestamp > T2.timestamp3
AND a.emp_id = T2.emp_id
AND a.status = 'out') as timestamp4
FROM T200 AS T2;
CREATE VIEW T400 AS
SELECT T3.emp_id,T3.status1,T3.timestamp1,T3.status2,T3.timestamp2,
T3.status3,T3.timestamp3,T3.status4,T3.timestamp4,
'in' as status5,
(SELECT min(timestamp)
FROM overallrec a
WHERE a.timestamp > T3.timestamp4
AND a.emp_id = T3.emp_id
AND a.status = 'in') as timestamp5
FROM T300 AS T3;
CREATE VIEW myFinalView AS
SELECT T4.emp_id,T4.status1,T4.timestamp1,T4.status2,T4.timestamp2,
T4.status3,T4.timestamp3,T4.status4,T4.timestamp4,T4.status5,T4.timestamp5,
'out' as status6,
(SELECT min(timestamp)
FROM overallrec a
WHERE a.timestamp > T4.timestamp5
AND a.emp_id = T4.emp_id
AND a.status = 'out') as timestamp6
FROM T400 AS T4;
所以我们有一个名为myFinalView
以下是带有备注的myFinalView
(请查看此sqlFiddle with remarks in the VIEW)