java - 右/左外连接 from() 和许多 'and' 与 JOOQ 中的四个表

标签 java sql oracle jooq

我是 JOOQ 的新手,需要帮助将 SQL 转换为 JOOQ。 所以我在这里有这么长的 SQL 语句:

请查看此图片以获得更好的洞察力:Outer Join

enter image description here

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、在SQL语句from中我有四个表,分别是deckagdvvsagvagd 表必须在 agd.agd_code(+) = deck.dec_agd_code 上与 deck 表连接。我是否正确翻译了 sql?
2. 我应该如何处理 vvsagv,因为这些表位于 from() 中的 agd 之后?


想了两天还是解决不了。

谢谢!

最佳答案

原始查询的 1:1 翻译

虽然我通常不推荐使用已弃用的 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 连接混用

除此之外,问题更容易解释。您将“经典”表列表(FROM 子句中的几个表)与 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();

关于java - 右/左外连接 from() 和许多 'and' 与 JOOQ 中的四个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45610241/

相关文章:

java - 将 TIMESTAMPWITH TIME ZONE 类型设置为 JDBC 可调用语句

java - 为什么在 java 类中包含类成员变量不像 ruby​​ mixin 那样?

java - Unresolved 类 '@string/appbar_scrolling_view_behavior'

java - 在sqlj中使用序列?

java - 如何为一个数据库写2个ip?

mysql - #1064 - 您的 SQL 语法有误;检查与您的 MySQL 服务器版本对应的手册以了解正确的语法

java - Java中如何从对象列表中获取单个对象

Java:检查哪些进程绑定(bind)到端口?

sql - 可串行化隔离级别原子性

javascript - "Unexpected token ."JSON 解析无法解析带前导零的十进制