如果count(*)>更新行ñ

时间:2013-10-10 13:26:30

标签: mysql sql insert sql-update

我的DB有这样的结构:

ID | text | time | valid

这是我目前的代码。我正试图找到一种方法来做这个查询。

rows = select * from table where ID=x order by time desc;
n=0;
foreach rows{
    if(n > 3){
       update table set valid = -1 where rows[n]; 
    }
    n++
}

我正在检查给定ID存在多少行。然后我需要为n> 3;

的所有行设置valid = -1

有没有办法用一个查询来做到这一点?

4 个答案:

答案 0 :(得分:3)

您可以在WHERE子句中使用子查询,如下所示:

UPDATE table
   SET valid=-1
 WHERE (
         SELECT COUNT(*)
           FROM table tt
          WHERE tt.time > table.time
            AND   tt.ID = table.ID
) > 3

子查询计算具有相同ID和更晚时间的行。对于最近的三行,此计数将为三或更少;其余的将有更多的计数,因此他们的valid字段将被更新。

答案 1 :(得分:2)

update table 
   set valid = -1
 where id in (select id
                from table 
               where id = GIVEN_ID
            group by id
              having count(1) >3)

更新:我真的很喜欢dasblinkenlight的解决方案,因为它非常整洁,但我想尝试以我的方式做到这一点,这是一个相当冗长的解决方案:

  update Table1
     set valid = -1
   where (id, time) in (select id, 
                               time
                          from (select id,time
                                  from table1
                                 where id in (select id
                                                from table1
                                            group by id
                                              having count(1) >3)
                                -- and id = GIVEN_ID
                              order by time 
                                 limit 3, 10000000) 
                        t);

同样在SQLFiddle

答案 2 :(得分:2)

假设(id,time)有一个UNIQUE约束,即没有两行具有相同的id和相同的time

UPDATE 
    tableX AS tu
  JOIN
    ( SELECT time
      FROM tableX
      WHERE id = @X                      -- the given ID
      ORDER BY time DESC
      LIMIT 1 OFFSET 2
    ) AS t3
    ON  tu.id = @X                       -- given ID again
    AND tu.time < t3.time 
SET
    tu.valid = -1 ;

答案 3 :(得分:0)

为所有ID执行此操作,或者仅在您在子查询中设置位置时执行一次

UPDATE TABLE
  LEFT JOIN (
              SELECT *
                FROM (
                       SELECT @rn:=if(@prv=id, @rn+1, 1) AS rId,
                              @prv:=id AS id,
                              TABLE.*
                         FROM TABLE
                         JOIN ( SELECT @prv:=0, @rn:=0 ) tmp
                        ORDER BY id, TIMESTAMP 
                     ) a
               WHERE rid > 3
             ) ordered ON ordered.id = TABLE.id
   AND ordered.TIMESTAMP = TABLE.TIMESTAMP
   AND ordered.text = TIMESTAMP.text
   SET VALID = -1
 WHERE rid IS NOT NULL