草庐IT

mysql - jOOQ 为嵌套选择生成的 SQL 在 MySQL/MariaDB 中不起作用

coder 2023-10-20 原文

对于经典排名问题(每个玩家最好的 3 个结果的总和)我使用 jOOQ DSLScala 提出了以下子查询(嵌入作为选择值并加入更复杂的查询中):

val tr1 = TOUR_RESULT.as("tr1")
val tr2 = TOUR_RESULT.as("tr2")
val inner:Table[Record1[java.lang.Integer]] = DSL.select(count().as("count")).from(tr2).where(tr1.PLAYER_ID.eq(tr2.PLAYER_ID).and(tr1.NSP_SCORE.le(tr2.NSP_SCORE))).asTable("tr3") 
val result = sql.select(tr1.PLAYER_ID,tr1.NSP_SCORE.sum().as("score"))
    .from(tr1)
    .where(inline(3).gt(sql.selectQuery(inner)))
    .groupBy(tr1.PLAYER_ID)
    .orderBy(2)
    .execute()

我目前的问题(使用 MariaDB 10 和 jOOQ 3.9)是让这个生成的查询完全与 MySQL 一起工作,并按“分数”(第 2 列)降序排序。 我相信我可以使用原始 SQL 语句重写整个语句并转换结果(因此绕过 jOOQ API)。但是,我想尽可能长时间地使用编译器和 jOOQ API 作为我的牧羊人。因此,如果我不得不再次触摸此查询,也许有一个解决方案在未来仍可读。

说明案例的模式和生成的 SQL 可以在下面找到 http://sqlfiddle.com/#!9/2f614f/3在评论中包含违规行/声明。

    create table TOUR_RESULT (
      player_id int,
      nsp_score int
    );

    insert into TOUR_RESULT values (1,4);
    insert into TOUR_RESULT values (1,14);
    insert into TOUR_RESULT values (1,24);
    insert into TOUR_RESULT values (1,34);
    insert into TOUR_RESULT values (1,44);
    insert into TOUR_RESULT values (2,3);
    insert into TOUR_RESULT values (2,13);
    insert into TOUR_RESULT values (2,23);
    insert into TOUR_RESULT values (2,33);
    insert into TOUR_RESULT values (2,43);
    insert into TOUR_RESULT values (3,3);
    insert into TOUR_RESULT values (3,13);
    insert into TOUR_RESULT values (4,130);
    insert into TOUR_RESULT values (5,2);
    insert into TOUR_RESULT values (5,7);
    insert into TOUR_RESULT values (5,7);
    insert into TOUR_RESULT values (5,7);
    insert into TOUR_RESULT values (5,5);
    insert into TOUR_RESULT values (5,7);
    insert into TOUR_RESULT values (5,10);
    insert into TOUR_RESULT values (5,12);

    SELECT `tr1`.`player_id`, sum(`tr1`.`nsp_score`) AS `score`
      FROM `tour_result` AS `tr1`
      WHERE 3 >=
    --    (SELECT `tr3`.`count`
    --     FROM
     (SELECT count(*) AS `count`
       FROM `tour_result` AS `tr2`
       WHERE (`tr1`.`player_id` = `tr2`.`player_id`
           AND `tr1`.`nsp_score` <= `tr2`.`nsp_score`)) 
    --               AS `tr3`)
    GROUP BY `tr1`.`player_id`
    ORDER BY 2 desc;

取消注释行时的错误是

    Unknown column 'tr1.player_id' in 'where clause'

最佳答案

不幸的是,MariaDB 和 MySQL 不允许在相关子查询中引用“两级以上”的列。但是如果你有 MariaDB 10.2 或 MySQL 8.0,你可以使用 window functions对于这份工作:

SQL 版本

SELECT tr1.player_id, SUM(nsp_score) AS score
FROM (
  SELECT 
    tr2.player_id, 
    tr2.nsp_score, 
    ROW_NUMBER () OVER (PARTITION BY tr2.player_id ORDER BY tr2.nsp_score DESC) rn
  FROM tour_result AS tr2
) AS tr1
WHERE rn <= 3
GROUP BY tr1.player_id;

ROW_NUMBER() 过滤将在分数中恰好选出 3 个获胜行。如果您想要 3 行或更多行,如果它们是并列的(WITH TIES 语义),您可以使用 RANK()I've also blogged about this topic in the past .

jOOQ版本

这转换为以下 jOOQ 查询:

val tr1 = TOUR_RESULT.as("tr1")
val tr2 = TOUR_RESULT.as("tr2")
val result = sql
    .select(tr1.PLAYER_ID, sum(tr1.NSP_SCORE).as("score"))
    .from(table(
       select(
         tr2.PLAYER_ID,
         tr2.NSP_SCORE,
         rowNumber().over(
           partitionBy(tr2.PLAYER_ID)
          .orderBy(tr2.NSP_SCORE.desc())).as("rn"))
      .from(tr2)
    ).as(tr1))
    .where(field(name("rn")).le(inline(3)))
    .groupBy(tr1.PLAYER_ID)
    .fetch()

以上是假设导入

import org.jooq.impl.DSL._

关于mysql - jOOQ 为嵌套选择生成的 SQL 在 MySQL/MariaDB 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50142330/

有关mysql - jOOQ 为嵌套选择生成的 SQL 在 MySQL/MariaDB 中不起作用的更多相关文章

  1. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  2. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  3. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  4. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  5. Ruby——嵌套类和子类是一回事吗? - 2

    下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby​​解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc

  6. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  7. ruby-on-rails - 使用回形针的嵌套形式 - 2

    我有一个名为posts的模型,它有很多附件。附件模型使用回形针。我制作了一个用于创建附件的独立模型,效果很好,这是此处说明的View(https://github.com/thoughtbot/paperclip):@attachment,:html=>{:multipart=>true}do|form|%>posts中的嵌套表单如下所示:prohibitedthispostfrombeingsaved:@attachment,:html=>{:multipart=>true}do|at_form|%>附件记录已创建,但它是空的。文件未上传。同时,帖子已成功创建...有什么想法吗?

  8. 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

  9. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  10. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

随机推荐