5

我的数据库有这样的结构:

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

4 回答 4

5

您可以在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字段将被更新。

于 2013-10-10T13:30:28.910 回答
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

于 2013-10-10T13:29:26.763 回答
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 ;
于 2013-10-10T14:17:13.137 回答
0

对所有 id 执行此操作,或者如果您在子查询中设置 where 则仅针对一个

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
于 2013-10-10T14:06:30.783 回答