【问题标题】:Delete singular entries删除单数条目
【发布时间】:2011-04-12 10:33:15
【问题描述】:

如果我有这张桌子:

+------+-------+---------------+--------+-----------------+------------+-----------+----------------+------+------+--------+------------+------------+
| type | class | username      | userid | userip          | usermobile | useremail | daysleft| pin1 | pin2 | pin3 | active | schoolname | schoolsite |
+------+-------+---------------+--------+-----------------+------------+-----------+----------------+------+------+--------+------------+------------+
| B    | A     | sebbetest     |   1000 | 123.123.123.123 | none       | none      |       50| 0    | 0    | 0    | Y      | none       | none       | 
| A    | A     | stackowerflow |   5355 | 123.123.123.123 | none       | none      |       50| 0    | 0    | 0    | Y      | none       | haha       | 
| C    | A     | good          |   4223 | 123.123.123.124 | none       | none      |       50| 0    | 0    | 0    | Y      | none       | haha       | 
| A    | A     | tester        |   6353 | 123.123.123.125 | none       | none      |       50| 0    | 0    | 0    | Y      | none       | haha       | 
| B    | A     | admin         |   3453 | 123.123.123.125 | none       | none      |       50| 0    | 0    | 0    | Y      | none       | eeee       | 
| A    | A     | sebastian     |   1342 | 123.123.123.126 | none       | none      |       50| 0    | 0    | 0    | Y      | none       | eeee       | 
| C    | A     | username      |   6456 | 123.123.123.125 | none       | none      |       50| 0    | 0    | 0    | Y      | none       | woooooow   | 
+------+-------+---------------+--------+-----------------+------------+-----------+----------------+------+------+--------+------------+------------+

如您所见,IP 为“123.123.123.124”的用户“good”和 IP 为“123.123.123.126”的用户“sebastian”没有“同伴”,同一 IP 上没有其他用户。

用户“sebbetest”有一个伴侣“stackowerflow”。

用户“tester”有 2 个同伴:“admin”和“username”。

现在我想删除这些缺少同伴的用户。我怎样做?出于原子原因和防止并发访问修改数据库,我想在单个 SQL 表达式中删除所有“非伴随”用户。

我尝试过: DELETE FROM WHERE COUNT(userip) = 1;

得到这个: ERROR 1111 (HY000): 组函数使用无效

没有行是重复的。 如果需要检查一个条目是否是唯一的,而不管 IP,(type, userid) 是唯一的。

也就是说,如果IP在一行中是唯一的,则删除它。

【问题讨论】:

    标签: mysql sql sql-delete mysql-error-1111


    【解决方案1】:

    用途:

    DELETE FROM lan
     WHERE userip IN (SELECT x.userip
                       FROM (SELECT yt.userip
                               FROM lan yt
                           GROUP BY yt.userip
                             HAVING COUNT(*) = 1) x )
    

    您收到错误是因为您在子查询之外无法使用 COUNT 或 WHERE 子句中的任何其他聚合函数。只有在HAVING 子句中才能以这种方式引用聚合函数。

    这可能会起作用:

      DELETE FROM lan 
    GROUP BY userip
      HAVING COUNT(*) = 1;
    

    警告

    对于每个 DELETE 语句,检查并仔细检查该语句是否会选择您要删除的内容。如果您使用 InnoDB 表,请将 DELETE 包装在事务中,以便您可以在必要时使用 ROLLBACK

    【讨论】:

    • mysql> DELETE FROM WHERE userip IN (SELECT yt.userip FROM lan yt GROUP BY yt.userip HAVING COUNT(*) = 1); ERROR 1093 (HY000): You can't specify target table 'lan' for update in FROM 子句
    • @sebastian nielsen:已修复,抱歉 - 忘记了 MySQL 的错误 1093 错误。
    【解决方案2】:

    我会这样做:

    DELETE l1
    FROM lan l1 LEFT OUTER JOIN lan l2 
      ON l1.userip = l2.userip AND l1.username <> l2.username
    WHERE l2.userid IS NULL
    

    换句话说,尝试使用外连接将l1 与其同伴l2 匹配。如果未找到匹配项,则 l2 将全部为空。如果发生这种情况,请删除 l1

    【讨论】:

    • +1:我默认使用最广泛支持的语法,不习惯 UPDATE & DELETE 中的 JOIN 支持...
    • 是的,如果 OP 没有标记这个 mysql 我不会建议它。但它是如此自然和有用的特性,我很惊讶它不是标准 SQL 的一部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    相关资源
    最近更新 更多