当前位置: 首页 > 知识库问答 >
问题:

右/左外部从()和许多“和”加入JOOQ中的四个表

申思远
2023-03-14

我是JOOQ的noob,需要帮助将SQL翻译成JOOQ。我这里有一个很长的SQL语句:

请看这张图片以更好地了解:外部连接

SELECT SUM(DECODE(VVS.VVS_ZWS_ID, 47, DECK.DEC_BRUTTOPRAEMIE_100,               DECK.DEC_BRUTTOPRAEMIE_FOLGE))
            FROM deck, agd, vvs, agv
            WHERE vvs.vvs_ver_nummer = verNummer
            AND vvs.vvs_nummer = vvsNummer 
            AND agv.agv_code = vvs.vvs_agv_code
            AND deck.dec_ver_nummer = vvs.vvs_ver_nummer
            AND deck.dec_vvs_nummer = vvs.vvs_nummer
            AND deck.dec_tbl_code = 'KH'
            AND agd.agd_code(+) = deck.dec_agd_code
            AND (    NVL(agv.agv_aenderungstyp, 'NULL') IN ('4', '5')
            OR NVL(agd.agd_aenderungstyp, 'NULL') NOT IN ('4', '5');

我将SQL声明翻译如下:

create.select(sum(decode().when(vvs.VVS_ZWS_ID.eq(47),deck.DEC_BRUTTOPRAEMIE_100)
                                    .otherwise(deck.DEC_BRUTTOPRAEMIE_FOLGE)))
            .from(deck, vvs, agv)
            .rightOuterJoin(agd)
            .on(agd.AGD_CODE.eq(deck.DEC_AGD_CODE))
            .where(vvs.VVS_VER_NUMMER.eq(verNummer))
            .and(vvs.VVS_NUMMER.eq(vvsNummer))
            .and(agv.AGV_CODE.eq(vvs.VVS_AGV_CODE))
            .and(deck.DEC_VER_NUMMER.eq(vvs.VVS_VER_NUMMER))
            .and(deck.DEC_VVS_NUMMER.eq(vvs.VVS_NUMMER))
            .and(deck.DEC_TBL_CODE.eq("KH"))
            .and(nvl(agv.AGV_AENDERUNGSTYP, "NULL")
              .in("4", "5")
              .or(nvl(agd.AGD_AENDERUNGSTYP, "NULL")
              .notIn("4", "5")))
            .fetch();

我的问题是:1<代码>agd表格必须与agd上的甲板表格连接。agd_代码()=甲板。dec_agd_代码。我是否正确翻译了sql
2.vvs和agv应该如何处理,因为这些表位于from()中agd的后面?


我花了两天时间思考这个问题,但我解决不了这个问题。

谢谢

共有1个答案

松和泰
2023-03-14

虽然我通常不建议使用已弃用的Oracle风格的外连接语法,但请注意,jOOQ确实通过Field.plus()支持它,因此您可以编写:

SQL

AND agd.agd_code(+) = deck.dec_agd_code

JOOQ

.and(agd.AGD_CODE.plus().eq(deck.DEC_AGD_CODE))

除此之外,这个问题更容易解释。您将“经典”表列表(来自子句中的几个表)与ANSI连接混合在一起,这总是令人困惑。使用jOOQ时,jOOQ会将ANSI连接表达式附加到表列表的最后一个表中。在您的情况下,这导致了以下FROM子句:

-- Parentheses added for illustration purposes
FROM deck, vvs, (agv RIGHT OUTER JOIN agd ON agd.AGD_CODE = deck.DEC_AGD_CODE)

在这种情况下,您可能需要的是LEFT OUTER JOIN,以防您的查询可能变得正确。

但这仍然会让人困惑,因此在任何情况下,我强烈建议您首先将查询迁移到所有ANSI连接:

SQL

SELECT SUM(DECODE(VVS.VVS_ZWS_ID, 
              47, DECK.DEC_BRUTTOPRAEMIE_100, 
              DECK.DEC_BRUTTOPRAEMIE_FOLGE))
FROM deck
JOIN vvs
  ON deck.dec_ver_nummer = vvs.vvs_ver_nummer
  AND deck.dec_vvs_nummer = vvs.vvs_nummer
JOIN agv
  ON agv.agv_code = vvs.vvs_agv_code
LEFT JOIN agd
  ON deck.dec_agd_code = agd.agd_code
WHERE vvs.vvs_ver_nummer = verNummer
  AND vvs.vvs_nummer = vvsNummer 
  AND deck.dec_tbl_code = 'KH'
  AND (    NVL(agv.agv_aenderungstyp, 'NULL') IN ('4', '5')
    OR NVL(agd.agd_aenderungstyp, 'NULL') NOT IN ('4', '5'));

JOOQ

create.select(sum(decode().when(vvs.VVS_ZWS_ID.eq(47),deck.DEC_BRUTTOPRAEMIE_100)
                                    .otherwise(deck.DEC_BRUTTOPRAEMIE_FOLGE)))
      .from(deck)
      .join(vvs)
        .on(deck.DEC_VER_NUMMER.eq(vvs.VVS_VER_NUMMER))
        .and(deck.DEC_VVS_NUMMER.eq(vvs.VVS_NUMMER))
      .join(agv)
        .on(agv.AGV_CODE.eq(vvs.VVS_AGV_CODE))
      .leftOuterJoin(agd)
        .on(agd.AGD_CODE.eq(deck.DEC_AGD_CODE))
      .where(vvs.VVS_VER_NUMMER.eq(verNummer))
      .and(vvs.VVS_NUMMER.eq(vvsNummer))
      .and(deck.DEC_TBL_CODE.eq("KH"))
      .and(nvl(agv.AGV_AENDERUNGSTYP, "NULL")
        .in("4", "5")
        .or(nvl(agd.AGD_AENDERUNGSTYP, "NULL")
        .notIn("4", "5")))
      .fetch();
 类似资料:
  • 问题内容: 我在定义为左外部联接的两个表上有一个联接,以便所有记录都从左表返回,即使它们在右表中没有记录也是如此。但是,我还需要在右侧表中的字段上包含where子句,但是....我仍然希望为左侧表中的每个记录返回左侧表中的一行,即使where子句中的条件不满足。有没有办法做到这一点? 问题答案: 是的,将条件(称为谓词)放入联接条件中

  • 我正在使用Symfony 3和教义2.5。总共有三张表: 给定公司id 2,最终结果应该是这样,但就我个人而言,我无法为它编写一个有效的原则QueryBuilder方法 我有三个可以工作的MySQL查询,它们为我带来了想要的结果。但就我的一生而言,我无法将任何一个问题转换成至少一个工作原理问题。 使用MySQL查询(这实际上可能会帮助这里的一些用户): 我在Doctrine的QueryBuilde

  • 问题内容: 我有三个表: 命令 OrderId,int PK CustomerId,与客户之间为int FK,允许为NULL 顾客 CustomerId,int PK CompanyId,将FK转换为Company,不允许为NULL 公司介绍 CompanyId,int PK 名称nvarchar(50) 我想选择所有订单,无论是否有客户,如果有客户,也要选择客户的公司名称。 如果我使用此查询…

  • 问题内容: 我正在尝试对齐包含3个内容块的顶部菜单。 我想要实现的是: 块1:左对齐 块2:水平居中 块3:右对齐 如果所有3个块的大小均相同,则可以使用flexbox(如代码段中所示),但是它们不是,所以不会产生我需要的输出。 相反,flexbox在3个块之间放置了相等的空间-导致中间块偏离中心对齐。 我想知道是否可以使用flexbox来实现,如果不能,则可以使用另一种解决方案。这需要在生产中稳

  • 问题内容: 我在SQL中有此查询,并且希望它使用Entity Framework 在LINQ中实现它,但是如何应用左外部联接的多个表? 问题答案: 这是使用LINQ实现左外部联接的方式。您应该使用GroupJoin(语法): 该查询联接了三个表。您可以以相同的方式加入其余表。

  • 如何在中实现或。一个简单的例子很有帮助。