草庐IT

MySQL Assign 在更新查询中只匹配一次

coder 2023-10-26 原文

我有两张表,一张有参与者和他们的排名,另一张有优惠券代码和他们的排名。我想为每个参与者分配一个具有正确等级的优惠券代码,但当然要确保每个优惠券代码只使用一次。

Table A:                             Table B:
pid | name | rank | voucherid        voucherid | rank | code | used
1   | Max  | 10   | null             1         | 10   | AAA  | 0
2   | Joe  | 20   | null             2         | 10   | BBB  | 0
3   | Eva  | 10   | null             3         | 20   | CCC  | 0
                                     4         | 20   | DDD  | 0

我正在寻找产生此结果的更新查询:

Table A:
pid | name | rank | voucherid
1   | Max  | 10   | 1
2   | Joe  | 20   | 3
3   | Eva  | 10   | 2

以下不起作用,因为它将同一张凭证分配给多个参与者:

UPDATE A
JOIN B ON A.`rank` = B.`rank`
SET A.`voucherid` = B.`voucherid`
WHERE
   A.`voucherid` IS NULL AND
   B.`used` = 0
;
-
Result:
Table A:
pid | name | rank | voucherid
1   | Max  | 10   | 1
2   | Joe  | 20   | 3
3   | Eva  | 10   | 1 !!!

之后我当然会更新凭证表 B,将 used 列设置为 1

最佳答案

我想我使用用户变量找到了答案,这就是为什么我要回答我自己的问题。

想法是使用一个计数器作为第二个比较变量,以确保将排名为 1 的凭证 1 分配给一个参与者,将排名为 1 的凭证 2 分配给另一个参与者。

MySQL查询比较繁琐。这就是为什么我可能使用 PHP 来解决问题。但我想分享它,至少:

UPDATE `A` AS ua
JOIN (

  SELECT
    ta.`participantid`, ta.`rank`, 
    (@ca := IF(@pa = ta.`rank`, @ca + 1, 0)) AS `counter`, 
    @pa := ta.`rank`
  FROM `A` AS ta, (SELECT @ca := 0, @pa := 0) AS ia
  WHERE
    ta.`voucherid` IS NULL
  ORDER BY `rank` ASC

) AS a ON a.`pid` = ua.`pid`
JOIN (

  SELECT
    tb.`voucherid`, tb.`rank`,
    (@cb := IF(@pb = tb.`rank`, @cb + 1, 0)) AS `counter`,
    @pb := tb.`rank`
  FROM `B` AS tb, (SELECT @cb := 0, @pb := 0) AS ib
  WHERE
    tb.`used` = 0
  ORDER BY `rank` ASC

) AS b ON (b.`rank` = a.`rank` AND b.`counter` = a.`counter`)
JOIN `B` AS ub ON ub.`voucherid` = b.`voucherid`
SET
  ua.`voucherid` = b.`voucherid`,
  ub.`used` = 1
;

它在我准备的测试用例中有效,但根据 MySQL documentation您不能依赖表达式的求值顺序。因此 @pa := ta.rank 可能会在 IF(@pa = ta.rank) 之前执行,这将导致错误的结果。

关于MySQL Assign 在更新查询中只匹配一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32461114/

有关MySQL Assign 在更新查询中只匹配一次的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  3. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  4. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  5. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  6. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  7. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  8. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  9. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  10. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

随机推荐