[英]SQL: update a row if *condition* on another row
我在SQL有問題。
當且僅當另一行上的值與條件匹配時,我想更新給定行上的值; 然后更新第二行的另一個值。
好吧,如果我這樣解釋就不清楚了,所以這里是代碼(我將使用mysqli綁定參數):
--mariaDB:
UPDATE `accountlist` JOIN `data` ON `accountlist`.`id`=`data`.`id`
SET `upvotes`= `upvotes` + (`user`= ?),
`allow` = (CASE WHEN `accountlist`.`id` = ?
THEN ?
ELSE `allow`
END)
WHERE (SELECT `allow` FROM `data` WHERE `id` = ?) < ?;
--mysql:
UPDATE `accountlist` JOIN `data` ON `accountlist`.`id`=`data`.`id`
SET `upvotes`= `upvotes` + (`user`= ?),
`allow` = (CASE WHEN `accountlist`.`id` = ?
THEN ?
ELSE `allow`
END)
WHERE `data`.`id` = ? AND `allow` < ?;
--params sample: "admin", 2, "2020-04-20", 2, "2020-04-20"
-- (same value here means always same value)
我必須保留 MySQL 和非 MySQL 版本,因為我在 localhost 和我的主機上有不同的數據庫,並且由於某種原因,第一個版本不適用於 MySQL。
data
是另一個與accountlist
具有一對一關系的表(它們總是具有相同的行數和相同的id
)
無論如何,我將調用user=?
第 1行和accountlist.id=?
所在的行第 2 行以簡化一切。
我想做的是:
allow
值小於,則更新第 1 行的user
?
allow
(如果第 2 行的allow
小於?
)第二點的條件並不重要,因為它會自我更新,但這是我能夠做到這一點的唯一方法。
我的問題:
upvotes
,但allow
第 2 行的更改。arrow
,但從不更改第 1 行的user
。您是否有任何解決方案,這可能意味着獨特的 MySQL + 非 MySQL 版本?
更新:
這里有一個例子:
accountlist data
|------------|---------------| |------------|--------------|----------|
| id | user | | id | allow | upvotes |
|------------|---------------| |------------|--------------|----------|
A: | 1 | admin | | 1 | 2020-04-18 | 2 |
B: | 2 | foo | | 2 | 2020-04-20 | 0 |
C: | 3 | bar | | 3 | 2020-04-22 | 1 |
|------------|---------------| |------------|--------------|----------|
params: "admin", 2, "2020-04-20", 2, "2020-04-20" allow
B 行不低於2020-04-20
:
params: "admin", 2, "2020-04-22", 2, "2020-04-22" allow
B 行低於2020-04-20
:
upvotes
增加( 2
-> 3
)allow
B 行已更新( 2020-04-20
-> 2020-04-22
) params: "bar", 1, "2020-04-19", 1, "2020-04-19" allow
A 行低於2020-04-19
:
upvotes
行的投票增加( 1
-> 2
)allow
A 行已更新( 2020-04-18
-> 2020-04-19
)更新 2:
我想做的事情:如果用戶 1想要投票給用戶 2 (每個人每天最多可以投票一次),當它點擊一個按鈕時, allowed
(在他的行上)與后一天進行比較:
allowed
等於day after ,則表示用戶 1已經為某人投票(他可能是用戶 2 、用戶 3或其他人),所以沒有任何變化allowed
低於day after ,則表示允許用戶 1對某人進行投票,因此對user 2的行的upvote
會遞增,而在user 1的行上的allow
會更新到后天不要擔心“如果用戶 1或用戶 2實際上不存在怎么辦?”,或者“如果用戶 1試圖給自己投票怎么辦?*因為我在我的PHP代碼中檢查了它。
讓我們來看看事情。 首先,讓每列限定以幫助查看哪一列在哪個表中:
UPDATE a JOIN d ON a.`id` = d.`id`
SET d.`upvotes`= d.`upvotes` + (a.`user`= ?),
d.`allow` = (CASE WHEN a.`id` = ?
THEN ?
ELSE d.`allow`
END)
WHERE d.`id` = ? AND d.`allow` < ?;
哦,這兩張桌子在id
上是 1:1 的。 所以讓我們假設它們是同一張桌子。 (你可能應該這樣做。1:1 通常不是一個好的模式設計。)
UPDATE ad
SET `upvotes`= `upvotes` + (`user`= ?),
`allow` = (CASE WHEN `id` = ?
THEN ?
ELSE `allow`
END)
WHERE `id` = ? AND `allow` < ?;
現在很明顯, CASE
被浪費了。 所以查詢簡化為
UPDATE ad
SET `upvotes`= `upvotes` + (`user`= ?),
`allow` = ?
WHERE `id` = ? AND `allow` < ?;
現在讓我們 go 回到有 2 個表:
UPDATE a JOIN d ON a.`id` = d.`id`
SET d.upvotes = d.upvotes + (a.user = ?),
d.allow = ?
WHERE d.id = ? AND d.allow < ?;
這導致了另一種形式。 (我不知道這是否更好。)
UPDATE d
SET d.upvotes = d.upvotes +
( ( SELECT user = ? FROM a WHERE a.id = d.id ) )
d.allow = ?
WHERE d.id = ? AND d.allow < ?;
或者,(同樣可能沒有任何顯着差異):
UPDATE d
SET d.upvotes = d.upvotes +
EXISTS ( SELECT user = ? FROM a WHERE a.id = d.id )
d.allow = ?
WHERE d.id = ? AND d.allow < ?;
我試圖為您的問題找到解決方案,我可能有一個答案,我在這里正確理解工作流程:每個用戶每天可以投票 1 次
在該示例中:“管理員”、2、“2020-04-20”、2、“2020-04-20”
我對么? 如果是的話,我的解決方案
mariadb
UPDATE data SET upvotes = CASE WHEN id = (SELECT id FROM accountlist WHERE accountlist.user = ?)
AND
(SELECT allow FROM data inner join accountlist on accountlist.id = data.id
where accountlist.id = ? )< ?
THEN upvotes + 1
ELSE upvotes
END,
allow = CASE WHEN id = ?
THEN ?
ELSE allow
END
mysql
UPDATE data
SET upvotes = CASE WHEN id = (SELECT id FROM (select * from accountlist) as al WHERE al.user = "bar")
AND
(SELECT allow FROM (select * from data) as d inner join (select * from accountlist) as al1 on al1.id = d.id where al1.id = 1)<"2020-04-19"
THEN upvotes + 1
ELSE upvotes
END,
allow = CASE WHEN id = 1
THEN "2020-04-19"
ELSE allow
END;
創建的數據庫:
accountlist data
|------------|---------------| |------------|--------------|----------|
| id | user | | id | allow | upvotes |
|------------|---------------| |------------|--------------|----------|
A: | 1 | admin | | 1 | 2020-04-18 | 2 |
B: | 2 | foo | | 2 | 2020-04-20 | 0 |
C: | 3 | bar | | 3 | 2020-04-22 | 1 |
|------------|---------------| |------------|--------------|----------|
具有值:“admin”、“2”、“2020-04-20”、“2”、“2020-04-20” => 無修改
“管理員”、“2”、“2020-04-22”、“2”、“2020-04-22”
accountlist data
|------------|---------------| |------------|--------------|----------|
| id | user | | id | allow | upvotes |
|------------|---------------| |------------|--------------|----------|
A: | 1 | admin | | 1 | 2020-04-18 | 3 |
B: | 2 | foo | | 2 | 2020-04-22 | 0 |
C: | 3 | bar | | 3 | 2020-04-22 | 1 |
|------------|---------------| |------------|--------------|----------|
"酒吧", 1, "2020-04-19", 1, "2020-04-19" =>
accountlist data
|------------|---------------| |------------|--------------|----------|
| id | user | | id | allow | upvotes |
|------------|---------------| |------------|--------------|----------|
A: | 1 | admin | | 1 | 2020-04-19 | 3 |
B: | 2 | foo | | 2 | 2020-04-22 | 0 |
C: | 3 | bar | | 3 | 2020-04-22 | 2 |
|------------|---------------| |------------|--------------|----------|
通常可以正確運行(在線測試),但使用 2 語句而不是 1 語句更簡單。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.