我有一个问题,在 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版本 因为我在本地主机和主机上有不同的数据库 由于某些原因,第一个版本不能与MySQL一起使用。
data
是另一个表,它与之有一对一的关系。accountlist
(它们总是有相同的行数,有相同的 id
s)
总之,我要把这一排的地方叫做 user=?
第1行 和所在行 accountlist.id=?
第二行 以简化一切。
我想做的是:
user
关于 第1行 如果 allow
关于 第二行 小于 ?
allow
关于 第二行 (如果 allow
关于 第二行 小于 ?
)第二点的条件并不重要,因为它会更新到自己身上,但这是我能够做到的唯一方法。
我的问题是
upvotes
关于 第1行 不变 allow
关于 第二行.arrow
关于 第二行 不变 user
关于 第1行.你有什么解决方案,这也许意味着一个独特的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"。"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"。"bar",1,"2020-04-19",1,"2020-04-19"allow
关于 一行 低于 2020-04-19
:
upvotes
关于 丙行 是增加(1
->2
)allow
关于 一行 是更新的(2020-04-18
->2020-04-19
)更新2。
我想做的是:如果 用户1 想加注 用户2 每个人每天最多可以给别人加一次票),当它点击一个按钮。allowed
与 后天:
allowed
等于 后天这意味着 用户1 已经给某人加了票(他可能是 用户2, 用户3 或别人),所以什么都没变allowed
低于 后天这意味着 用户1 允许给某人加票,所以 upvote
关于 用户2的行被递增,并且 allow
关于 用户1的行更新为 后天不要担心 "如果 用户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` < ?;
哦,这两张表是1: 1的,在... id
. 所以让我们假设它们是同一个表。 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` < ?;
现在让我们回到有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次。
在该示例中:"admin",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"=> 没有修改。
"admin"、"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 |
|------------|---------------| |------------|--------------|----------|
"bar", 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个。