You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL删除指定ID的非min()/max()时间数据时误删全部数据,求解决方法

问题描述

我需要删除指定ID(1、3、4、5、6、7)中除min(jam)和max(jam)之外的冗余时间记录,仅保留每个ID的这两个极值数据。我尝试编写了SQL语句,但执行多次后指定ID的所有记录被意外删除,以下是详细情况:

原SQL语句

DELETE FROM table1
WHERE ID_karyawan IN (1, 3, 4, 5, 6, 7) -- 目标ID列表
  AND jam NOT IN (SELECT MIN(jam) 
                  FROM table1 
                  WHERE ID_karyawan IN (1, 3, 4, 5, 6, 7)
                  UNION
                  SELECT MAX(jam) 
                  FROM table1 
                  WHERE ID_karyawan IN (1, 3, 4, 5, 6, 7)
                 );

SELECT 
    table1.ID_karyawan, table1.nama_karyawan, 
    table1.jam, table1.tanggal, table1.arah
FROM 
    table1 
GROUP BY 
    ID_karyawan, nama_karyawan, jam, tanggal, arah

原数据

ID karyawan nama karyawan       jam          tanggal    arah
-------------------------------------------------------------
1   ridho azhar megantara     07:44:45    2023-07-20  masuk
1   ridho azhar megantara     17:04:46    2023-07-20  keluar
3   Hendy Arief Yuwono        17:24:47    2023-07-20  keluar
3   Hendy Arief Yuwono        06:58:41    2023-07-20  masuk
3   Hendy Arief Yuwono        17:24:41    2023-07-20  keluar
4   Ety wulandari             07:51:48    2023-07-20  masuk
4   Ety wulandari             17:04:07    2023-07-20  keluar
5   Joseph Tan                17:03:48    2023-07-20  keluar
5   Joseph Tan                07:40:31    2023-07-20  masuk
6   Herry Joko Susilo         17:04:16    2023-07-20  keluar
6   Herry Joko Susilo         07:26:11    2023-07-20  masuk
6   Herry Joko Susilo         07:26:16    2023-07-20  masuk
7   Martha Ayu Wulandari      07:49:53    2023-07-20  masuk
7   Martha Ayu Wulandari      07:50:23    2023-07-20  masuk
7   Martha Ayu Wulandari      17:04:43    2023-07-20  keluar

期望结果

ID karyawan nama karyawan       jam          tanggal    arah
-----------------------------------------------------------
1   ridho azhar megantara     07:44:45    2023-07-20  masuk
1   ridho azhar megantara     17:04:46    2023-07-20  keluar
3   Hendy Arief Yuwono        06:58:41    2023-07-20  masuk
3   Hendy Arief Yuwono        17:24:41    2023-07-20  keluar
4   Ety wulandari             07:51:48    2023-07-20  masuk
4   Ety wulandari             17:04:07    2023-07-20  keluar
5   Joseph Tan                17:03:48    2023-07-20  keluar
5   Joseph Tan                07:40:31    2023-07-20  masuk
6   Herry Joko Susilo         07:26:11    2023-07-20  masuk
6   Herry Joko Susilo         17:04:16    2023-07-20  keluar
7   Martha Ayu Wulandari      07:49:53    2023-07-20  masuk
7   Martha Ayu Wulandari      17:04:43    2023-07-20  keluar

实际问题

执行上述SQL多次后,指定ID的记录被大量删除,例如ID3仅剩下非期望的记录,甚至最终可能被全部删除:

3   Hendy Arief Yuwono        06:58:41    2023-07-20 00:00:00.000
3   Hendy Arief Yuwono        17:24:47    2023-07-20 00:00:00.000

错误原因分析

你的SQL核心问题在于:子查询是针对所有指定ID的整体取MIN(jam)和MAX(jam),而不是每个ID单独取自己的极值。

比如所有指定ID中,整体最小的jam是ID3的06:58:41,整体最大的是ID3的17:24:47。第一次执行DELETE时,所有jam不是这两个值的指定ID记录都会被删掉——包括ID1的07:44:45和17:04:46、ID4的所有记录等。第二次执行时,剩下的记录的jam会形成新的整体极值范围,导致更多记录被删除,最终指定ID的记录可能被清空。


修正方案

需要按ID_karyawan分组,获取每个ID自己的MIN(jam)和MAX(jam),再删除不在对应ID极值列表中的记录。以下是两种可行的写法:

方法一:使用关联子查询

DELETE t1
FROM table1 t1
WHERE t1.ID_karyawan IN (1, 3, 4, 5, 6, 7)
  AND t1.jam NOT IN (
      SELECT jam 
      FROM (
          SELECT ID_karyawan, MIN(jam) AS jam FROM table1 WHERE ID_karyawan IN (1, 3, 4, 5, 6, 7) GROUP BY ID_karyawan
          UNION ALL
          SELECT ID_karyawan, MAX(jam) AS jam FROM table1 WHERE ID_karyawan IN (1, 3, 4, 5, 6, 7) GROUP BY ID_karyawan
      ) t2
      WHERE t2.ID_karyawan = t1.ID_karyawan
  );

方法二:使用CTE(适用于支持CTE的数据库如MySQL 8+、SQL Server等)

WITH KaryawanExtremes AS (
    SELECT 
        ID_karyawan,
        MIN(jam) AS min_jam,
        MAX(jam) AS max_jam
    FROM table1
    WHERE ID_karyawan IN (1, 3, 4, 5, 6, 7)
    GROUP BY ID_karyawan
)
DELETE t1
FROM table1 t1
JOIN KaryawanExtremes ke ON t1.ID_karyawan = ke.ID_karyawan
WHERE t1.jam NOT IN (ke.min_jam, ke.max_jam);

验证建议

执行DELETE前,建议先把语句改成SELECT,确认要删除的记录是否正确:

-- 验证要删除的记录
SELECT *
FROM table1 t1
WHERE t1.ID_karyawan IN (1, 3, 4, 5, 6, 7)
  AND t1.jam NOT IN (
      SELECT jam 
      FROM (
          SELECT ID_karyawan, MIN(jam) AS jam FROM table1 WHERE ID_karyawan IN (1, 3, 4, 5, 6, 7) GROUP BY ID_karyawan
          UNION ALL
          SELECT ID_karyawan, MAX(jam) AS jam FROM table1 WHERE ID_karyawan IN (1, 3, 4, 5, 6, 7) GROUP BY ID_karyawan
      ) t2
      WHERE t2.ID_karyawan = t1.ID_karyawan
  );

内容的提问来源于stack exchange,提问作者unlimited system

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:00:53