这是我的表的示例输出(time_entries)
user_name| entry_type | entry_datetime
User1 | Time In | 28-JUL-13 16:40:40
User1 | Time Out | 28-JUL-13 16:40:41
User2 | Time In | 28-JUL-13 16:41:13
User2 | Time Out | 28-JUL-13 16:41:15
User1 | Time In | 27-JUL-13 16:42:30
User1 | Time Out | 27-JUL-13 16:42:34
User2 | Time In | 27-JUL-13 16:43:32
User2 | Time Out | 27-JUL-13 16:43:35
现在我使用了这个查询
SELECT te.user_name, te.entry_name, MAX(te.entry_datetime) AS date
FROM time_entries AS te
GROUP BY te.entry_type, te.user_name
结果是这样的
user_name| entry_type | entry_datetime
User1 | Time In | 28-JUL-13 16:40:40
User1 | Time Out | 28-JUL-13 16:40:41
User2 | Time In | 28-JUL-13 16:41:13
User2 | Time Out | 28-JUL-13 16:41:15
题: 有没有办法在1行合并用户名和相同名称?并有一个像这样的输出。
user_name| Date | Timein | Timeout
User1 | 28-JUL-13 | 16:40:40 | 16:40:41
User2 | 28-JUL-13 | 16:41:13 | 16:41:15
我有点混淆怎么做。
我会以这种方式接近它:
- 创建一个查询,返回每个用户和日期的“时间”时间。
- 创建一个像#1这样的查询,返回每个用户和日期的“超时”时间。
- 使用LEFT JOIN将结果合并在一起。
最终结果:
SELECT te.user_name, LEFT(te.entry_datetime, 10) AS entry_date, cin.entry_datetime AS timein, cout.entry_datetime AS timeout
FROM time_entries te
LEFT JOIN (SELECT user_name, LEFT(entry_datetime, 10) AS entry_date, MIN(entry_datetime) AS entry_datetime
FROM time_entries
WHERE entry_type = 'Time In'
GROUP BY user_name, entry_date
) cin ON cin.user_name = te.user_name AND cin.entry_date = LEFT(te.entry_datetime, 9)
LEFT JOIN (SELECT user_name, LEFT(entry_datetime, 10) AS entry_date, MAX(entry_datetime) AS entry_datetime
FROM time_entries
WHERE entry_type = 'Time Out'
GROUP BY user_name, entry_date
) cout ON cout.user_name = te.user_name AND cout.entry_date = LEFT(te.entry_datetime, 10)
GROUP BY te.user_name, entry_date;
演示
顺便说一下,我正在使用 LEFT()
这是因为您的列不包含MySQL理解的实际日期格式。
那这个呢?
select
user_name,
date(entry_datetime) as date,
min(entry_datetime) as Timein,
max(entry_datetime) as Timeout
from (
SELECT te.user_name, te.entry_name, MAX(te.entry_datetime) AS date
FROM time_entries AS te
GROUP BY te.entry_type, te.user_name) src
group by user_name, date
这是一个关于如何处理数据的php端解决方案。
function transformArray($data) {
$final = array();
foreach ($data as $key => $row) {
if (!isset($final[$row['u']])) $final[$row['u']] = array('user' => $row['u']);
$final[$row['u']][$row['t']] = date("H:i:s", strtotime($row['entrydatetime']));
$final[$row['u']]['date'] = date("d:M:y", strtotime($row['entrydatetime']));
}
return $final;
}
您可以向它传递一个看起来像这样的数据集,您可以将字段名称调整为nessecery。
$data = array(
array('u' => 'user1', 't' => 'TimeIn', 'entrydatetime' => '28-JUL-13 16:40:40'),
array('u' => 'user1', 't' => 'TimeOut', 'entrydatetime' => '28-JUL-13 16:40:40'),
array('u' => 'user2', 't' => 'TimeIn', 'entrydatetime' => '28-JUL-13 16:40:40'),
array('u' => 'user2', 't' => 'TimeOut', 'entrydatetime' => '28-JUL-13 16:40:40')
);
这将完成工作:
SELECT te.user_name,DATE(te.entry_datetime) as Date,te.entry_datetime AS TimeIn,te2.entry_datetime AS TimeOut
FROM time_entries te
JOIN time_entries te2 ON te.user_name=te2.user_name AND te2.entry_type="Time Out" AND
te2.entry_datetime=
(
SELECT
entry_datetime
FROM
time_entries
WHERE entry_type='Time Out' AND user_name=te.user_name AND entry_datetime > te.entry_datetime
ORDER BY
ABS(TIMESTAMPDIFF(SECOND, te.entry_datetime, `entry_datetime`))
LIMIT 1
)
WHERE te.entry_type="Time In";
编辑:一点解释:
它为TimeIn部分选择user_name,date部分和entry_datetime。然后它连接在同一个表上以获取Time Out datetime部分。它通过选择具有相同user_name的类型“Time Out”的条目和最接近Time In datetime的日期来完成此操作。
select
user_name,
dATE(entry_datetime) AS date1,
min(entry_datetime) as Timein,
max(entry_datetime) as Timeout
from time_entries
group by user_name, date1
SqlFiddleDemo
对于每个Time_In,此查询将正常工作
相应的超时。并且每个新的一天入场类型都应该
从time_in开始