Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 用于删除的SQL查询_Mysql_Sql_Database - Fatal编程技术网

Mysql 用于删除的SQL查询

Mysql 用于删除的SQL查询,mysql,sql,database,Mysql,Sql,Database,考虑下表 id || C1 || C2 || C3 || Timestamp -------------------------------- 1 || a || b || 1 || t1 2 || a || b || 1 || t2 3 || a || b || 2 || t3 4 || a || b || 2 || t4 5 || a || b || 2 || t5 6 || b || d || 3 |

考虑下表

id  || C1  || C2  || C3 || Timestamp
--------------------------------
1   || a   || b   || 1  || t1
2   || a   || b   || 1  || t2
3   || a   || b   || 2  || t3
4   || a   || b   || 2  || t4
5   || a   || b   || 2  || t5
6   || b   || d   || 3  || t6
7   || b   || d   || 3  || t7
C3包含给定C1和C2组合的不同值。C1、C2和C3的给定组合可以具有具有不同时间戳的多行,如行4、5

然而,对于给定的C1和C2对,重复会导致创建多个C3。因此,这里第3、4和5行违反了规则,因为引入了新的C32。给定C1和C2,C3总是唯一的

我想保留C1、C2、C3的最新w.r.t时间戳组合,并删除所有旧的。因此,只应存在第3、4、5行,而应删除第1、2行。 我的意思是,对于给定的C1,C2,旧的C3值应该被删除,所以在这种情况下,行1,2被删除,但3,4,5仍然保留

例如,给定唯一的nid和原始列,应该删除所有具有mock_id YR的行


我尝试过各种查询和联接,但无法找到解决此问题的方法。

我们可以尝试在此处使用exists逻辑:

DELETE
FROM yourTable t1
WHERE EXISTS (SELECT 1 FROM yourTable t2
              WHERE t2.C1 = t1.C1 AND t2.C2 = t1.C2 AND t2.C3 > t1.C3);
简单地说,这个查询表示删除任何记录,对于这些记录,我们可以找到另一个具有相同C1和C2值,但C3值更大的记录。如果存在这样的另一个记录,则意味着当前正在检查的记录不是最新的,应该删除

C3包含给定C1和C2组合的不同值

那么应该有两张桌子。一个为每个C1/C2对分配一个C3,另一个包含C1+C2或C3以及timstamp

无论如何,您要删除具有不同C3的同一C1/C2对存在较新时间戳的所有行:

delete from mytable
where exists
(
  select null
  from (select * from mytable) newer
  where newer.c1 = mytable.c1
    and newer.c2 = mytable.c2
    and newer.c3 <> mytable.c3
    and newer.timestamp > mytable.timestamp
);
在MySQL中,从select*from mytable newer而不仅仅是从from mytable newer写入是必要的,因为存在一个奇怪的限制,即您不能在更新或删除中直接使用同一个表。

在MySQL中,使用JOIN和GROUP BY:


下面是我针对我的问题提出的解决方案,它在测试数据集上运行良好。戈顿的回答很接近,但得出的逻辑与蒂姆提供的相同。我对此做了一些修改,只获取最新的C3值,然后删除此集合中不存在的值

由于mysql错误阻止通过from子句更新目标表,我不得不使用from两次。下面是一个更好地解释这个问题的例子

delete from strings where strings.C3 not in 
( select C3 from 
    ( select C3 from strings join 
        ( select C1, C2, max(timestamp) as max_timestamp from strings group by C1, C2 ) t2
        on strings.C1 = t2.C1
        and strings.C2 = t2.C2
        and strings.Timestamp = max_timestamp 
    ) as t3
);

这个问题每天被正确地问和回答好几次。请注意,对于大型数据集,可以更快地构造一个新表,只保留所需的数据,然后用该表替换旧表。此外,您给出的预期输出与前面的句子不一致。我对问题进行了编辑,以提供更清晰的信息。考虑C3作为一个独特的哈希值,C1,C2应该只有一个,但不知何故,我现在得到了另一个C3。所以我需要删除包含旧C3值的行。嗨,蒂姆。我相信这个解决方案只会产生具有最新时间戳的C1、C2、C3的不同组合。我只想删除额外的C3组合。@arjunkhera我已根据您更新的逻辑对我的答案进行了轻微编辑。如果值总是按顺序递增,我会这样做,但这里不是这样。时间戳似乎不相关,问:我的答案下面的评论。@Tim Biegeleisen:在arjunkhera评论提到的最后一次编辑之前,你的答案看起来和我的几乎一样,但是你的答案是t2.C3=t1.C3。因此,您没有按照请求删除旧的不同的C3,而是按照C1/C2/C3保留所有最新的行。我确实认为时间戳很重要,我们不应该依赖于新的C3大于以前的C3。我确信我的查询是正确的。如果相同的C3不能出现在不同的C1/C2对中,那么这是可行的。我觉得我的答案更具可读性,但你是对的,MySQL在更新或删除中使用同一个表时存在问题,通常通过从mytable替换为从select*从mytable来避免这个问题。我会相应地更新我的答案。我仍然认为您面临的主要问题是有缺陷的数据模型,这使得不一致性成为可能。C3的值总是不同的。因此,对于任何给定的C1/C2对,它总是唯一的。我在我的问题中提到过,我继承了这个数据库,需要尽快解决这个问题。但是,感谢您的建议,在将其转移到新方案时,请记住,对于C1/C2对,C3被认为是唯一的,这本质上就是问题所在,因为您现在必须删除不一致的其他C3。但是其他C1/C2呢?他们能有相同的C3吗?如果是这样,则delete语句是不够的。
delete from strings where strings.C3 not in 
( select C3 from 
    ( select C3 from strings join 
        ( select C1, C2, max(timestamp) as max_timestamp from strings group by C1, C2 ) t2
        on strings.C1 = t2.C1
        and strings.C2 = t2.C2
        and strings.Timestamp = max_timestamp 
    ) as t3
);