无论如何我可以删除某个表(users
)中的所有重复条目吗?这是我所拥有的条目类型的示例。我必须说表users
包含3个字段, ID
, user
和 pass
mysql_query("DELETE FROM users WHERE ???") or die(mysql_error());
randomtest
randomtest
randomtest
nextfile
baby
randomtest
dog
anothertest
randomtest
baby
nextfile
dog
anothertest
randomtest
randomtest
我希望能够找到重复的条目,然后删除所有重复项,然后保留一个。
答案 0 :(得分:5)
您可以使用三个平方码来完成:
create table tmp as select distinct name from users;
drop table users;
alter table tmp rename users;
答案 1 :(得分:4)
您只需一个查询即可解决此问题。
如果您的表格具有以下结构:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL auto_increment,
`username` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
你可以做类似的事情(这将删除所有重复的用户,基于用户名和ID大于该用户名的较小ID):
DELETE users
FROM users INNER JOIN
(SELECT MIN(id) as id, username FROM users GROUP BY username) AS t
ON users.username = t.username AND users.id > t.id
它有效并且我已经使用了类似删除副本的东西。
答案 2 :(得分:1)
此删除脚本(SQL Server语法)应该有效:
DELETE FROM Users
WHERE ID NOT IN (
SELECT MIN(ID)
FROM Users
GROUP BY User
)
答案 3 :(得分:1)
我假设您有如下结构:
users
-----------------
| id | username |
-----------------
| 1 | joe |
| 2 | bob |
| 3 | jane |
| 4 | bob |
| 5 | bob |
| 6 | jane |
-----------------
由于MySQL无法在使用删除目标表的删除查询中使用子选择,因此需要使用临时魔术。
CREATE TEMPORARY TABLE IF NOT EXISTS users_to_delete (id INTEGER);
INSERT INTO users_to_delete (id)
SELECT MIN(u1.id) as id
FROM users u1
INNER JOIN users u2 ON u1.username = u2.username
GROUP BY u1.username;
DELETE FROM users WHERE id NOT IN (SELECT id FROM users_to_delete);
我知道查询有点毛茸茸,但即使用户表的列数超过2列,也能正常工作。
答案 4 :(得分:1)
您需要小心如何使用表中的数据。如果这确实是一个用户表,则可能有其他表FK指向ID列。在这种情况下,您需要更新这些表以使用您选择保留的ID。
如果它只是一个独立的表(没有表引用它)
CREATE TEMPORARY TABLE Tmp (ID int);
INSERT INTO Tmp SELECT ID FROM USERS GROUP BY User;
DELETE FROM Users WHERE ID NOT IN (SELECT ID FROM Tmp);
从其他表格链接的用户表
创建临时表,包括一个包含所有旧id的链接表以及其他表应引用的相应新id。
CREATE TEMPORARY TABLE Keep (ID int, User varchar(45));
CREATE TEMPORARY TABLE Remove (OldID int, NewID int);
INSERT INTO Keep SELECT ID, User FROM USERS GROUP BY User;
INSERT INTO Remove SELECT u1.ID, u2.ID FROM Users u1 INNER JOIN Keep u2 ON u2.User = u1.User WHERE u1.ID NOT IN (SELECT ID FROM Users GROUP BY User);
浏览任何引用您的users表的表并更新其FK列(可能称为UserID)以指向您选择的新唯一ID,如此...
UPDATE MYTABLE t INNER JOIN Remove r ON t.UserID = r.OldID
SET t.UserID = r.NewID;
最后返回到您的用户表并删除不再引用的重复项:
DELETE FROM Users WHERE ID NOT IN (SELECT ID FROM Keep);
清理那些Tmp表:
DROP TABLE KEEP;
DROP TABLE REMOVE;
答案 5 :(得分:0)
一个非常简单的解决方案是在表格的列上设置一个UNIQUE
索引,以获得唯一值。请注意,您随后无法两次插入相同的密钥。
编辑:我的错误,我没有读到最后一行:“我希望能够找到重复的条目”。
答案 6 :(得分:0)
我会得到所有结果,将它们放入ID和VALUES数组中。使用PHP函数计算出数据,记录数组中的所有ID,并使用这些值删除记录。
答案 7 :(得分:0)
我不知道您的数据库模式,但最简单的解决方案似乎是在该表上执行SELECT DISTINCT
,将结果保存在变量(即数组)中,从表中删除所有记录然后重新插入该列表之前由SELECT DISTINCT
返回。
答案 8 :(得分:0)
临时表是一个很好的解决方案,但我想提供一个SELECT
查询,从表中抓取重复的行作为替代:
SELECT * FROM `users` LEFT JOIN (
SELECT `name`, COUNT(`name`) AS `count`
FROM `users` GROUP BY `name`
) AS `grouped`
WHERE `grouped`.`name` = `users`.`name`
AND `grouped`.`count`>1
答案 9 :(得分:0)
这将有效:
create table tmp like users;
insert into tmp select distinct name from users;
drop table users;
alter table tmp rename users;
答案 10 :(得分:0)
根据您的表格结构选择3列,并根据您的要求应用条件。
SELECT user.userId,user.username user.password FROM user As user GROUP BY user.userId,user.username HAVING(COUNT(user.username)> 1));
答案 11 :(得分:0)
上面和/或下面的每个答案对我都不起作用,因此我决定编写自己的小脚本。这不是最好的,但它完成了工作
评论包含在内,但是这个脚本是根据我的需求定制的,我希望这个想法对你有帮助。
我基本上将数据库内容写入临时文件,称为临时文件,将函数应用于被调用文件以删除重复项,截断表,然后将数据直接输入到SQL中。听起来很多,我知道。
如果您对 $setprofile
的内容感到困惑,那么这是在登录我的脚本(建立个人资料)时创建的会话,并在注销时被清除。
<?php
// session and includes, you know the drill.
session_start();
include_once('connect/config.php');
// create a temp file with session id and current date
$datefile = date("m-j-Y");
$file = "temp/$setprofile-$datefile.txt";
$f = fopen($file, 'w'); // Open in write mode
// call the user and pass via SQL and write them to $file
$sql = mysql_query("SELECT * FROM _$setprofile ORDER BY user DESC");
while($row = mysql_fetch_array($sql))
{
$user = $row['user'];
$pass = $row['pass'];
$accounts = "$user:$pass "; // the white space right here is important, it defines the separator for the dupe check function
fwrite($f, $accounts);
}
fclose($f);
// **** Dupe Function **** //
// removes duplicate substrings between the seperator
function uniqueStrs($seperator, $str) {
// convert string to an array using ' ' as the seperator
$str_arr = explode($seperator, $str);
// remove duplicate array values
$result = array_unique($str_arr);
// convert array back to string, using ' ' to glue it back
$unique_str = implode(' ', $result);
// return the unique string
return $unique_str;
}
// **** END Dupe Function **** //
// call the list we made earlier, so we can use the function above to remove dupes
$str = file_get_contents($file);
// seperator
$seperator = ' ';
// use the function to save a unique string
$new_str = uniqueStrs($seperator, $str);
// empty the table
mysql_query("TRUNCATE TABLE _$setprofile") or die(mysql_error());
// prep for SQL by replacing test:test with ('test','test'), etc.
// this isn't a sufficient way of converting, as i said, it works for me.
$patterns = array("/([^\s:]+):([^\s:]+)/", "/\s++\(/");
$replacements = array("('$1', '$2')", ", (");
// insert the values into your table, and presto! no more dupes.
$sql = 'INSERT INTO `_'.$setprofile.'` (`user`, `pass`) VALUES ' . preg_replace($patterns, $replacements, $new_str) . ';';
$product = mysql_query($sql) or die(mysql_error()); // put $new_str here so it will replace new list with SQL formatting
// if all goes well.... OR wrong? :)
if($product){ echo "Completed!";
} else {
echo "Failed!";
}
unlink($file); // delete the temp file/list we made earlier
?>
答案 12 :(得分:-1)
如果桌面上有唯一ID /主键,则:
DELETE FROM MyTable AS T1 WHERE MyID < ( SELECT MAX(MyID) FROM MyTable AS T2 WHERE T2.Col1 = T1.Col1 AND T2.Col2 = T1.Col2 ... repeat for all columns to consider duplicates ... )
如果您没有唯一键,请将所有不同的值选择到临时表中,删除所有原始行,并从临时表中复制回来 - 但如果您有外键引用此表,则会出现问题