V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
coderstory
V2EX  ›  MySQL

not in 查不到数据 求大佬解答

  •  
  •   coderstory ·
    coderstory · 2023-03-03 15:32:24 +08:00 · 1312 次点击
    这是一个创建于 666 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有个表 id 列是可重复的 tid 列是不重复的 现在需要按 id 列分组 删除 分组后第一条之后的数据

    SELECT tid FROM task_info group by id

    查询到数据 这些 tid 是需要保留的

    523763312515
    531589750696
    609232912408
    791117856085
    840800426753
    939049452487
    

    这个查询是查询需要删除的数据 排除需要保留的就是需要删除的

    select * FROM task_info where tid not in (SELECT tid FROM task_info group by id)

    但实际这个语句查不到任何数据 tid 的数据类型是 bigint

    not in 改成 in 又能查到全部数据

    5 条回复    2023-03-04 01:46:25 +08:00
    tbv
        1
    tbv  
       2023-03-03 16:07:45 +08:00
    尝试使用以下查询语句:

    SELECT id, MIN(tid) AS first_tid
    FROM task_info
    GROUP BY id;

    这将先按 id 分组,然后对于每个分组,选择最小的 tid 值作为“第一条数据”。然后,你可以在使用这个查询结果的基础上重新构建你的表。

    以下是一个例子:

    WITH first_tids AS (
    SELECT id, MIN(tid) AS first_tid
    FROM task_info
    GROUP BY id
    )
    SELECT *
    FROM task_info
    WHERE (id, tid) IN (SELECT id, first_tid FROM first_tids);

    这将选择每个分组中的第一条数据,即具有最小 tid 值的数据,并从原始表中保留这些数据,而删除其他数据。
    (以上来自于 chatgpt )
    liprais
        2
    liprais  
       2023-03-03 16:12:35 +08:00
    用 not exists
    iacker
        3
    iacker  
       2023-03-03 16:28:52 +08:00
    应该是有 null 值
    wander555
        4
    wander555  
       2023-03-03 16:31:48 +08:00
    您所提供的 SQL 查询语句中存在问题。在使用 not in 子句时,如果子查询返回的结果集中存在 NULL 值,那么主查询将不会返回任何结果,这可能会导致结果不符合预期。因此,您可以使用 not exists 子句来避免这个问题。

    以下是一个可能的解决方案:

    sql
    Copy code
    DELETE FROM task_info t1
    WHERE EXISTS (
    SELECT 1 FROM task_info t2
    WHERE t1.id = t2.id AND t1.tid > t2.tid
    );
    这个查询将按照 id 列进行分组,并删除每组中 tid 列的第一个之后的所有行。

    请注意,这个查询可能会删除与您提供的保留的 tid 列中的值相同的行。如果您想保留这些行,请将子查询的 WHERE 子句中的 NOT 删除。

    sql
    Copy code
    DELETE FROM task_info t1
    WHERE EXISTS (
    SELECT 1 FROM task_info t2
    WHERE t1.id = t2.id AND t1.tid > t2.tid
    AND t2.tid NOT IN (523763312515, 531589750696, 609232912408, 791117856085, 840800426753, 939049452487)
    );
    这个查询将保留与您提供的保留的 tid 列中的值相同的行。
    OOKAMI
        5
    OOKAMI  
       2023-03-04 01:46:25 +08:00
    考虑一下将分组第一行的数据写到新表,清空原表再塞回去?

    CREATE TABLE NEW_TABLE AS
    SELECT ID,TID FROM (
    SELECT ID,TID, RANK() OVER(PARTITION BY ID ORDER BY TID) AS RANK FROM TASK_INFO
    ) WHERE RANK=1;

    DELETE FROM TASK_INFO;

    INSERT INTO TASK_INFO
    SELECT * FROM NEW_TABLE;
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2500 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 05:28 · PVG 13:28 · LAX 21:28 · JFK 00:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.