2013-10-10 30 views
2

我DB具有這樣的結構:更新行,如果count(*)>ñ

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有多少行。那麼我需要爲所有行設置有效值= -1,其中n> 3;

有沒有辦法用一個查詢來做到這一點?

+0

見:http://stackoverflow.com/questions/2334712/update-from-select-using-sql-server和http://stackoverflow.com/questions/1262786/mysql-update-query基於選擇查詢 –

回答

1

假設(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 ; 
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

+0

這將設置「有效」爲 - 1在總計數大於3的所有行上.OP的循環保持前三行不變,在第4行之後的所有內容上將'valid'設置爲'-1'。 – dasblinkenlight

+0

你是對的,我錯過了那部分 – mucio

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字段將被更新。

+0

我得到這個錯誤,當我嘗試這個:http://stackoverflow.com/questions/45494/mysql-error-1093-cant-specify-target-table-for-update-in -from-clause –

+0

只有1個表... –

+0

@FrancisSnipe讓我試着構建一個ideone演示。你使用的是什麼版本的MySql? – dasblinkenlight

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