Php 如何在mysql中不删除组内所有记录
我正在使用考勤管理系统。我必须准备一些报告,包括每个员工的指纹记录。我想要一张板条箱表格,上面显示日期以及与该日期相关的所有时间。使用下面的查询,我得到了这样的结果Php 如何在mysql中不删除组内所有记录,php,mysql,sql,Php,Mysql,Sql,我正在使用考勤管理系统。我必须准备一些报告,包括每个员工的指纹记录。我想要一张板条箱表格,上面显示日期以及与该日期相关的所有时间。使用下面的查询,我得到了这样的结果 SELECT * FROM `attendancedata` where `EnrolledID`= 23 GROUP BY Date,EnrolledID,Time ORDER BY Date DESC,Time DESC EnrolledID Date Time 23 2019-09-09 07:58:
SELECT * FROM `attendancedata` where `EnrolledID`= 23 GROUP BY
Date,EnrolledID,Time ORDER BY Date DESC,Time DESC
EnrolledID Date Time
23 2019-09-09 07:58:36
23 2019-09-07 17:25:00
23 2019-09-07 16:08:27
23 2019-09-07 07:32:39
23 2019-09-06 16:00:10
23 2019-09-06 07:48:51
23 2019-09-05 16:00:23
23 2019-09-05 07:40:55
23 2019-09-04 16:00:39
23 2019-09-04 07:45:42
23 2019-09-03 16:00:06
23 2019-09-03 07:43:32
23 2019-09-02 16:00:04
23 2019-09-02 07:56:25
我的预期结果是
Date P01 P02 P03 P04 P05 P06 P07
2019-09-02 07:56:25 16:00:04
2019-09-03 07:43:32 16:00:06
2019-09-04 07:45:42 16:00:39
2019-09-05 07:40:55 16:00:23
2019-09-06 07:48:51 16:00:10
2019-09-07 07:32:39 16:08:27 17:25:00
2019-09-08 07:58:36
我如何解决这个问题?(打孔时间限制为最多7次)
(使用query或使用php)如果您使用的是MySQL 8+,我们可以使用
行号处理此问题:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Date ORDER BY Time) rn
FROM attendancedata
WHERE EnrolledID = 23
)
SELECT
Date,
MAX(CASE WHEN rn = 1 THEN Time END) AS PO1,
MAX(CASE WHEN rn = 2 THEN Time END) AS PO2,
MAX(CASE WHEN rn = 3 THEN Time END) AS PO3,
MAX(CASE WHEN rn = 4 THEN Time END) AS PO4,
MAX(CASE WHEN rn = 5 THEN Time END) AS PO5,
MAX(CASE WHEN rn = 6 THEN Time END) AS PO6,
MAX(CASE WHEN rn = 7 THEN Time END) AS PO7
FROM cte
GROUP BY
Date
ORDER BY
Date;
但请注意,一般情况下,最好使用MySQL将日期和时间存储在单个datetime
字段中。在这种情况下,结果很好,但这可能并不总是正确的。我相信您正在尝试按日期分组。你可以试试这个
SELECT Date, JSON_ARRAYAGG(Time) as times FROM attendancedata GROUP BY Date.
MySQL 5.7及更低版本:
- 使用MySQL变量根据
日期
和时间
进行排名。我们已经假设它只针对一个用户
- 当
通过聚合对派生结果使用大小写,并将信息拆分为7列
我们有完全相同的出勤数据表,我进行了一些查询,以检索与您所需类似的最终结果。试试下面这个:
SELECT EnrolledID,DATE,
SUBSTRING_INDEX(TimeAttList,' ',1) AS 'P01',
CASE WHEN TotalCheckin >=2 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(TimeAttList,' ',2),' ',-1) END AS 'P02',
CASE WHEN TotalCheckin >=3 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(TimeAttList,' ',3),' ',-1) END AS 'P03',
CASE WHEN TotalCheckin >=4 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(TimeAttList,' ',4),' ',-1) END AS 'P04',
CASE WHEN TotalCheckin >=5 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(TimeAttList,' ',5),' ',-1) END AS 'P05',
CASE WHEN TotalCheckin >=6 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(TimeAttList,' ',6),' ',-1) END AS 'P06',
CASE WHEN TotalCheckin =7 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(TimeAttList,' ',7),' ',-1) END AS 'P07'
FROM
(SELECT EnrolledID,DATE,GROUP_CONCAT(TIME ORDER BY TIME ASC SEPARATOR ' ') AS 'TimeAttList',COUNT(*) AS 'TotalCheckin'
FROM `attendancedata`
WHERE `EnrolledID`= 1
GROUP BY EnrolledID, DATE ORDER BY DATE ASC,TIME ASC) A;
我正在使用MySQL 4.1。
我首先使用了GROUP\u CONCAT
,其中包含ORDER BY
。这将列出所有时间,如下所示:
+------------+------------+-------------------------------------------------------+--------------+
| EnrolledID | Date | TimeAttList | TotalCheckin |
+------------+------------+-------------------------------------------------------+--------------+
| 1 | 2019-06-24 | 08:53:01 12:02:17 12:35:33 18:04:57 | 4 |
| 1 | 2019-06-25 | 09:01:13 12:00:13 12:59:23 18:17:32 | 4 |
| 1 | 2019-06-26 | 08:54:10 12:03:32 13:00:37 18:03:56 | 4 |
| 1 | 2019-06-27 | 08:53:46 12:01:49 12:56:30 18:17:31 | 4 |
| 1 | 2019-06-28 | 08:59:31 11:03:31 11:58:59 17:03:10 17:58:31 21:05:58 | 6 |
| 1 | 2019-06-29 | 08:58:50 11:01:54 11:59:51 17:05:01 18:01:05 21:08:48 | 6 |
| 1 | 2019-06-30 | 09:01:13 11:00:49 12:00:03 17:04:42 18:00:17 20:14:28 | 6 |
| 1 | 2019-07-01 | 10:53:00 15:04:06 16:01:18 20:00:21 | 4 |
+------------+------------+-------------------------------------------------------+--------------+
我将基设置为子查询,然后使用SUBSTRING\u INDEX
分离组\u CONCAT
结果:
+------------+------------+----------+----------+----------+----------+----------+----------+-----+
| EnrolledID | DATE | P01 | P02 | P03 | P04 | P05 | P06 | P07 |
+------------+------------+----------+----------+----------+----------+----------+----------+-----+
| 1 | 2019-06-24 | 08:53:01 | 12:02:17 | 12:35:33 | 18:04:57 | | | |
| 1 | 2019-06-25 | 09:01:13 | 12:00:13 | 12:59:23 | 18:17:32 | | | |
| 1 | 2019-06-26 | 08:54:10 | 12:03:32 | 13:00:37 | 18:03:56 | | | |
| 1 | 2019-06-27 | 08:53:46 | 12:01:49 | 12:56:30 | 18:17:31 | | | |
| 1 | 2019-06-28 | 08:59:31 | 11:03:31 | 11:58:59 | 17:03:10 | 17:58:31 | 21:05:58 | |
| 1 | 2019-06-29 | 08:58:50 | 11:01:54 | 11:59:51 | 17:05:01 | 18:01:05 | 21:08:48 | |
| 1 | 2019-06-30 | 09:01:13 | 11:00:49 | 12:00:03 | 17:04:42 | 18:00:17 | 20:14:28 | |
| 1 | 2019-07-01 | 10:53:00 | 15:04:06 | 16:01:18 | 20:00:21 | | | |
+------------+------------+----------+----------+----------+----------+----------+----------+-----+
如果与特定日期相关的次数超过5次怎么办?最多7次broTry MySQL变量进行
排名
,然后使用case当
@NipunSachinda时,验证我的答案,它适用于MySQL 5.7或更低版本。此查询对我不起作用。关键字not recognition语句出现错误。我认为MySQL版本存在问题。如果不使用行号
,在MySQL中很难做到这一点。JSON_ArrayAg的含义是什么?请注意:JSON_ArrayAg不存在。它将在MySQL 5.7+中可用。您使用的是哪个版本?4.8.5版本我认为这解决了我的问题。当我检查查询时,我将标记为正确答案。非常感谢您的宝贵帮助非常有用。感谢您的宝贵贡献@NipunSachinda。巧合的是,我们有相同的表结构和要求。@tvadidot0,很好的一个,绝对更容易理解的格式。我忍不住要做voteup。为了表现,是的。BczSUBSTRING\u INDEX
的成本很高,您使用它的次数也更多。在我的查询中,简单变量执行任务,而CASE WHEN
用于提取数据。尝试这两种解决方案,并让我们知道它们在大数据集上的表现。在我在远程服务器上进行的4次测试中(ping延迟约3毫秒),我发现使用子字符串_INDEX
的查询平均在1.489秒内更快。在执行每个查询之前,我用MySQL flush做了另一个测试,差异增大了-SUBSTRING\u INDEX
快了14.208秒-292871行>输出68824行。在另一个远程服务器上(ping延迟约16ms),CASE
查询执行速度加快8.109秒(1个测试)-437793行>输出101329行(更大的数据)。我正在检查两台服务器之间的表索引是否不同。
+------------+------------+----------+----------+----------+----------+----------+----------+-----+
| EnrolledID | DATE | P01 | P02 | P03 | P04 | P05 | P06 | P07 |
+------------+------------+----------+----------+----------+----------+----------+----------+-----+
| 1 | 2019-06-24 | 08:53:01 | 12:02:17 | 12:35:33 | 18:04:57 | | | |
| 1 | 2019-06-25 | 09:01:13 | 12:00:13 | 12:59:23 | 18:17:32 | | | |
| 1 | 2019-06-26 | 08:54:10 | 12:03:32 | 13:00:37 | 18:03:56 | | | |
| 1 | 2019-06-27 | 08:53:46 | 12:01:49 | 12:56:30 | 18:17:31 | | | |
| 1 | 2019-06-28 | 08:59:31 | 11:03:31 | 11:58:59 | 17:03:10 | 17:58:31 | 21:05:58 | |
| 1 | 2019-06-29 | 08:58:50 | 11:01:54 | 11:59:51 | 17:05:01 | 18:01:05 | 21:08:48 | |
| 1 | 2019-06-30 | 09:01:13 | 11:00:49 | 12:00:03 | 17:04:42 | 18:00:17 | 20:14:28 | |
| 1 | 2019-07-01 | 10:53:00 | 15:04:06 | 16:01:18 | 20:00:21 | | | |
+------------+------------+----------+----------+----------+----------+----------+----------+-----+