SQL:如果*条件*在另一行上,则更新一行。

我有一个问题,在 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 (它们总是有相同的行数,有相同的 ids)

总之,我要把这一排的地方叫做 user=? 第1行 和所在行 accountlist.id=? 第二行 以简化一切。

我想做的是:

  1. 更新 user 关于 第1行 如果 allow 关于 第二行 小于 ?
  2. 更新 allow 关于 第二行 (如果 allow 关于 第二行 小于 ?)

第二点的条件并不重要,因为它会更新到自己身上,但这是我能够做到的唯一方法。

我的问题是

  • 第一段代码(非MySQL)会更新… … upvotes 关于 第1行 不变 allow 关于 第二行.
  • 第二段代码(MySQL)更新 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 < ?;

给TA打赏
共{{data.count}}人
人已打赏
解决方案

Powershell和IBMLotus Domino。

2022-5-12 13:00:12

解决方案

Angular 8:从 "url "加载模块被阻止,因为不允许使用MIME类型("texthtml")。

2022-5-12 13:00:16

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索