MYSQL删除 - 表'USER_TABLE'被指定两次,既作为'DELETE'的目标又作为单独的数据源

时间:2017-09-05 08:12:58

标签: mysql sql sql-server database relational-database

我是MySql大型查询的新手,并试图为我的问题找到一些解决方案,

我希望根据 USER_TABLE 中的“ID_object”列删除重复值。

这是我的USER_TABLE描述,

`USER_TABLE` (
  `ID` varchar(256) NOT NULL,
  `ID_OBJECT` varchar(256) DEFAULT NULL,
  `INSERTION_TIME` date DEFAULT NULL,
  KEY `USER_TABLE_inx01` (`ID`(255)),
  KEY `user_inx02` (`ID_OBJECT`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我尝试了以下查询来删除重复的ID_OBJECT,

delete from USER_TABLE  where id in (
select ID from USER_TABLE,
(select ID_OBJECT, min(INSERTION_TIME) as fecha from USER_TABLE group by ID_OBJECT having count(ID_OBJECT)>1) tbpr 
where USER_TABLE.ID_OBJECT = tbpr.ID_OBJECT and USER_TABLE.INSERTION_TIME=tbpr.fecha);

但它说,  SQL Error (1093): Table 'USER_TABLE' is specified twice, both as a target for 'DELETE' and as a separate source for data

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:2)

这样做。我没有尝试检查您删除重复项的实际业务逻辑是否正确,因为您声明的要求无论如何都不是100%明确,但这是您可以克服错误消息的一种方法:

CREATE TEMPORARY TABLE IF NOT EXISTS duplicates AS (
SELECT UT.id 
FROM `USER_TABLE` AS UT
INNER JOIN
  (SELECT
    ID_OBJECT, 
    MIN(INSERTION_TIME) AS fecha 
  FROM `USER_TABLE` 
  GROUP BY ID_OBJECT 
  HAVING COUNT(ID_OBJECT)>1) AS tbpr 
ON
  UT.ID_OBJECT = tbpr.ID_OBJECT AND UT.INSERTION_TIME = tbpr.fecha
);

DELETE FROM `USER_TABLE`
WHERE id IN (SELECT id FROM duplicates);

DROP TABLE IF EXISTS duplicates;

您可以在此处查看有效的演示:https://www.db-fiddle.com/f/amnAPUftLD1SmW67fjVSEv/0

答案 1 :(得分:1)

您可以稍微更改您的查询

delete from USER_TABLE  
where concat(id_object,insertion_time) in 
(
select concat(ID_object,fecha) from
(
select ID_OBJECT, min(INSERTION_TIME) as fecha 
from USER_TABLE 
group by ID_OBJECT 
having count(ID_OBJECT)>1
) tbpr 
) 

但是这不能应付三重奏,四胞胎等等。所以也许你需要反转逻辑并且只保留最大值有倍数

delete from USER_TABLE  
where concat(id_object,insertion_time) not in 
(
select concat(ID_object,fecha) from
(
select ID_OBJECT, max(INSERTION_TIME) as fecha 
from USER_TABLE 
group by ID_OBJECT 
having count(ID_OBJECT)>1
) tbpr 
) 
and
id_object not in
(
select ID_object from
(
select ID_OBJECT, count(*) as fecha 
from USER_TABLE 
group by ID_OBJECT 
having count(ID_OBJECT) = 1
) tbpr2 
)
;

create table `USER_TABLE` (
  `ID` varchar(256) NOT NULL,
  `ID_OBJECT` varchar(256) DEFAULT NULL,
  `INSERTION_TIME` date DEFAULT NULL,
  KEY `USER_TABLE_inx01` (`ID`(255)),
  KEY `user_inx02` (`ID_OBJECT`(255))
) ;
truncate table user_table;
insert into user_table values
(1,1,'2017-01-01'),(2,1,'2017-01-02'),(3,1,'2017-01-03'),
(4,2,'2017-01-01');

第一次查询的结果

MariaDB [sandbox]> select * from user_table;
+----+-----------+----------------+
| ID | ID_OBJECT | INSERTION_TIME |
+----+-----------+----------------+
| 2  | 1         | 2017-01-02     |
| 3  | 1         | 2017-01-03     |
| 4  | 2         | 2017-01-01     |
+----+-----------+----------------+
3 rows in set (0.00 sec)

第二次查询的结果

MariaDB [sandbox]> select * from user_table;
+----+-----------+----------------+
| ID | ID_OBJECT | INSERTION_TIME |
+----+-----------+----------------+
| 3  | 1         | 2017-01-03     |
| 4  | 2         | 2017-01-01     |
+----+-----------+----------------+
2 rows in set (0.00 sec)