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 · 1081 次点击
    这是一个创建于 437 天前的主题,其中的信息可能已经有所发展或是发生改变。

    腾讯云最新优惠活动来了:云产品限时1折,云服务器低至88元/年 ,点击这里立即抢购:9i0i.cn/qcloud,更有2860元代金券免费领取,付款直接抵现金用,点击这里立即领取:9i0i.cn/qcloudquan

    (福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

    现在有个表 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   ·   实用小工具   ·   6545 人在线   最高记录 6548   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 01:59 · PVG 09:59 · LAX 18:59 · JFK 21:59
    Developed with CodeLauncher
    ? Do have faith in what you're doing.


    http://www.vxiaotou.com