当前位置:网站首页>Automatic conversion of Oracle-style implicit joins to ANSI JOINs using jOOQ
Automatic conversion of Oracle-style implicit joins to ANSI JOINs using jOOQ
2022-08-02 00:32:00 【YYniannian】

虽然jOOQ主要被用作Javaembedded dynamicSQL的内部SQL DSL,It offers the best solution on the market,但jOOQIt is also increasingly being used for one of its secondary functions.在jOOQ 3.9中引入的解析器Mainly to be able to解析DDL语句,For example reverse engineering your schema for code generation purposes,We have added more and more features and SQL转换能力,Enables the parser as a standalone product,通过命令行界面、我们的网站or by ordinaryjOOQ API来使用. 在jOOQ 3.14中增加的一个功能,Mainly for those usejOOQUseful as a profiler,就是将旧的OracleStyle implicit joins are converted to ANSI JOIN的能力.
为什么要避免 "隐式连接"?
大多数RDBMSVendors all support the old onesOraclestyle implicit join syntax,and optimized appropriately.在过去,在SQL-92之前,This is what we use to internally join tables,例如,在查询Sakila数据库时.
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id
AND fa.film_id = f.film_id
复制代码诚然,This syntax is very intuitive.Just declare all the tables you want to get data from,Then make sure to only filter by matching primary keys/foreign key values to hold the appropriate data. 当然,This can go horribly wrong.For many obvious reasons,例如,When you forget a join predicate after adding a table.If the query is complex,This can be hard to debug.解决方案是ANSI JOIN.从SQL-92开始(差不多30年了!),That's what we are in mostRDBMSconnection in .
SELECT *
FROM actor a
JOIN film_actor fa ON a.actor_id = fa.actor_id
JOIN film f ON fa.film_id = f.film_id
复制代码Although it is still possible to define the wrong join predicate,But at least it is no longer possible to forget a predicate,Because this is grammatically incorrect(除了MySQL,遗憾的是,在那里,ON子句是可选的).
SELECT *
FROM actor a
JOIN film_actor fa -- Syntax error
JOIN film f -- Syntax error
复制代码jOOQ的隐式JOIN
注意,People usually refer to the above syntax as "隐式连接",而JPQL和jOOQAnother one was recycled"隐式连接 "的术语,It is based on foreign key paths,甚至比ANSI SQLThe syntax is less error-prone.使用jOOQ,The above query can be written as follows.
ctx.select(
FILM_ACTOR.actor().asterisk(),
FILM_ACTOR.asterisk(),
FILM_ACTOR.film().asterisk())
.from(FILM_ACTOR)
.fetch();
复制代码These exist only in the queryto-one的关系路径,will be implicitly appropriateLEFT JOIN 或INNER JOIN 添加到FROM 子句中.It's just normalANSI JOIN之上的便利,而不是替代.
改造Oracle的隐式连接
When you have an old codebase,You want to upgrade and convert all queries to useANSI JOIN时,请使用jOOQ来实现.你可以使用jOOQ的编程功能(如前所述),or free websitewww.jooq.org/translate.在网站上,只需选择 "Oracle风格到ANSI JOIN "选项,Place the following on the leftSQL:输入
SELECT
a.first_name,
a.last_name,
count(c.category_id)
FROM
actor a,
film_actor fa,
film f,
film_category fc,
category c
WHERE a.actor_id = fa.actor_id
AND fa.film_id = f.film_id
AND fc.category_id = c.category_id
GROUP BY
a.actor_id,
a.first_name,
a.last_name
复制代码输出
SELECT
a.first_name,
a.last_name,
count(c.category_id)
FROM actor a
JOIN film_actor fa
ON a.actor_id = fa.actor_id
JOIN film f
ON fa.film_id = f.film_id
CROSS JOIN (
film_category fc
JOIN category c
ON fc.category_id = c.category_id
)
GROUP BY
a.actor_id,
a.first_name,
a.last_name
复制代码然后......呼啦啦.The output shows the result correctly,不需要的CROSS JOIN,Because one of the join predicates is missing:是的,This tool has been of great help!Let's fix the query entered.Let's fix the query entered:Correct input
SELECT
a.first_name,
a.last_name,
count(c.category_id)
FROM
actor a,
film_actor fa,
film f,
film_category fc,
category c
WHERE a.actor_id = fa.actor_id
AND fa.film_id = f.film_id
AND f.film_id = fc.film_id -- This was missing
AND fc.category_id = c.category_id
GROUP BY
a.actor_id,
a.first_name,
a.last_name
复制代码固定输出
SELECT
a.first_name,
a.last_name,
count(c.category_id)
FROM actor a
JOIN film_actor fa
ON a.actor_id = fa.actor_id
JOIN film f
ON fa.film_id = f.film_id
JOIN film_category fc
ON f.film_id = fc.film_id
JOIN category c
ON fc.category_id = c.category_id
GROUP BY
a.actor_id,
a.first_name,
a.last_name
复制代码如果你使用OracleThe arcane outer join syntax(+) (或者SQL Server的*= ,It has been unsupported for a while),这也是可行的.You may have such an input:输入
SELECT
a.first_name,
a.last_name,
count(c.category_id)
FROM
actor a,
film_actor fa,
film f,
film_category fc,
category c
WHERE a.actor_id = fa.actor_id(+)
AND fa.film_id = f.film_id(+)
AND f.film_id = fc.film_id(+)
AND fc.category_id(+) = c.category_id
GROUP BY
a.actor_id,
a.first_name,
a.last_name
复制代码产生这样的输出
SELECT
a.first_name,
a.last_name,
count(c.category_id)
FROM actor a
LEFT OUTER JOIN film_actor fa
ON a.actor_id = fa.actor_id
LEFT OUTER JOIN film f
ON fa.film_id = f.film_id
LEFT OUTER JOIN (
film_category fc
RIGHT OUTER JOIN category c
ON fc.category_id = c.category_id
)
ON f.film_id = fc.film_id
GROUP BY
a.actor_id,
a.first_name,
a.last_name
复制代码呃,哇.又来了!其中一个(+) The symbol is on the wrong side,That's why we got thisRIGHT OUTER JOIN .This tool shows again,The old syntax is error-prone.Let's fix it.Correct input
SELECT
a.first_name,
a.last_name,
count(c.category_id)
FROM
actor a,
film_actor fa,
film f,
film_category fc,
category c
WHERE a.actor_id = fa.actor_id(+)
AND fa.film_id = f.film_id(+)
AND f.film_id = fc.film_id(+)
AND fc.category_id = c.category_id(+)
GROUP BY
a.actor_id,
a.first_name,
a.last_name
复制代码固定输出
SELECT
a.first_name,
a.last_name,
count(c.category_id)
FROM actor a
LEFT OUTER JOIN film_actor fa
ON a.actor_id = fa.actor_id
LEFT OUTER JOIN film f
ON fa.film_id = f.film_id
LEFT OUTER JOIN film_category fc
ON f.film_id = fc.film_id
LEFT OUTER JOIN category c
ON fc.category_id = c.category_id
GROUP BY
a.actor_id,
a.first_name,
a.last_name
复制代码总结
玩一玩,告诉我们你的想法!
学习的节奏慢一点效果才能更好!希望这篇文章对各位有所帮助!共勉.
边栏推荐
- async/await 原理及执行顺序分析
- Simpson's paradox
- 632. Minimum interval
- [21-Day Learning Challenge] A small summary of sequential search and binary search
- CRS 管理与维护
- The Statement update Statement execution
- 【解决】win10下emqx启动报错Unable to load emulator DLL、node.db_role = EMQX_NODE__DB_ROLE = core
- IO流基础
- [HCIP] BGP Small Experiment (Federation, Optimization)
- 微软电脑管家V2.1公测版正式发布
猜你喜欢

双队列实现栈?双栈实现队列?

Unknown CMake command “add_action_files“

146. LRU cache

Short video SEO optimization tutorial Self-media SEO optimization skills and methods
![[21-Day Learning Challenge] A small summary of sequential search and binary search](/img/81/7339a33de3b9e3aec0474a15825a53.png)
[21-Day Learning Challenge] A small summary of sequential search and binary search

nodeJs--mime模块

Short video seo search optimization main content

面试:简单介绍你参与的一个项目

短视频seo搜索优化主要内容

IP Core: FIFO
随机推荐
认识USB、Type-C、闪电、雷电接口
06-SDRAM : SDRAM control module
[HCIP] BGP Small Experiment (Federation, Optimization)
测试点等同于测试用例吗
[头条]笔试题——最小栈
Industrial control network intrusion detection based on automatic optimization of hyperparameters
辨析内存函数memset、memcmp、memmove以及memcpy
Async/await principle and execution sequence analysis
面试高频考题解法——栈的压入弹出序列、有效的括号、逆波兰表达式求值
Multi-feature fusion face detection based on attention mechanism
els 方块边界变形处理
els 方块变形
07-SDRAM: FIFO control module
Active Disturbance Rejection Control of Substation Inspection Robot Based on Data Drive
电机原理动图合集
【加密周报】经济衰退在加息气氛中蔓延 美联储“放手一搏”?盘点上周加密市场发生的重大事件
SphereEx Miao Liyao: Database Mesh R&D Practice under Cloud Native Architecture
An interesting project--Folder comparison tool (1)
【无标题】
磁盘与文件系统管理
