从具有超过500行的类别中删除一些随机行

时间:2013-10-18 11:22:55

标签: mysql sql

我有一些类别,其中有一些行..

在某些类别中包含非常少的行,在某些其他类别中包含大约5000行..

我需要的是: 在一个类别中,如果在该catgeory中有超过500行,则应该删除一些随机行。总体而言,每个类别中最多500行应该存在..梦想的行应该被删除(无论它们有多少......)< / p>

我不明白如何在mysql中编写查询,任何人都可以帮我解决这个问题吗?

编辑: 我的桌子就像这个当下......

**CATEGORIES|NO OF ROWS**
========================
CAT1|500
CAT2|5000
CAT3|20
CAT4|50
CAT5|4000

NO OF ROWS :来自各个类别的所有行数!

现在CAT2和CAT5的行数超过500行,因此剩下的行应该从这两个类别中删除..(注意:我不想再删除哪些行,你可以在随机删除它们..)

3 个答案:

答案 0 :(得分:0)

我希望这对你有所帮助。

DELETE FROM TABLENAME 

WHERE (SELECT COUNT(*) FROM TABLENAME > 500)

ORDER BY RAND() 

LIMIT 10

限制10是您想要的删除次数。

答案 1 :(得分:0)

考虑以下内容......

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table (category_id INT NOT NULL,val INT NOT NULL,PRIMARY KEY(category_id,val));

INSERT INTO my_table VALUES (1,101),(1,102),(1,103),(1,104),(2,103),(2,104),(2,105),(3,104),(3,105),(4,106);

SELECT * FROM my_table;
+-------------+-----+
| category_id | val |
+-------------+-----+
|           1 | 101 |
|           1 | 102 |
|           1 | 103 |
|           1 | 104 |
|           2 | 103 |
|           2 | 104 |
|           2 | 105 |
|           3 | 104 |
|           3 | 105 |
|           4 | 106 |
+-------------+-----+

SELECT x.*
     , COUNT(*) rank 
  FROM my_table x 
  JOIN my_table y 
    ON y.category_id = x.category_id 
   AND RAND(y.val) <= RAND(x.val) 
 GROUP 
    BY x.category_id
     , x.val
 ORDER BY category_id
     , rank;
+-------------+-----+------+
| category_id | val | rank |
+-------------+-----+------+
|           1 | 104 |    1 |
|           1 | 101 |    2 |
|           1 | 102 |    3 |
|           1 | 103 |    4 |
|           2 | 104 |    1 |
|           2 | 105 |    2 |
|           2 | 103 |    3 |
|           3 | 104 |    1 |
|           3 | 105 |    2 |
|           4 | 106 |    1 |
+-------------+-----+------+

所以,假设我们要考虑排名高于'2'的所有行,那么这个查询可以重写如下......

 SELECT x.*
   FROM my_table x 
   JOIN my_table y 
     ON y.category_id = x.category_id 
    AND RAND(y.val) <= RAND(x.val) 
  GROUP 
     BY x.category_id
      , x.val
 HAVING COUNT(*)> 2;

...然后可以通过JOIN的简单代理转换为DELETE

 DELETE a FROM my_table a
   JOIN 
      ( SELECT x.*
          FROM my_table x 
          JOIN my_table y 
            ON y.category_id = x.category_id 
           AND RAND(y.val) <= RAND(x.val) 
         GROUP 
            BY x.category_id
             , x.val
        HAVING COUNT(*)> 2
      ) b 
     ON b.category_id = a.category_id
    AND b.val = a.val;

 Query OK, 3 rows affected (0.08 sec)

 SELECT * FROM my_table;
 +-------------+-----+
 | category_id | val |
 +-------------+-----+
 |           1 | 101 |
 |           1 | 104 |
 |           2 | 104 |
 |           2 | 105 |
 |           3 | 104 |
 |           3 | 105 |
 |           4 | 106 |
 +-------------+-----+
 7 rows in set (0.00 sec)

答案 2 :(得分:-1)

<强>您好,

根据我的理解,你有一个CategoryDe​​tails TABLE,每个CategoryID有多个记录。并且您需要为每个CategoryID维护最多500条记录。

根据上述理解,我使用SQL CTE为您提供以下解决方案。如果我错了,请详细解释您的查询。

WITH cteCategoryDetails AS (
SELECT ROW_NUMBER() OVER (PARTITION BY CategoryID, STATE ORDER BY CategoryID) AS RowNum  FROM CategoryDetails
) DELETE FROM cteCategoryDetails WHERE RowNum > 500

谢谢, Vishal Patel

相关问题