SlideShare a Scribd company logo
1 of 124
Download to read offline
@vlad_mihalcea vladmihalcea.com
Awesome
SQL
Tips and Tricks
@vlad_mihalcea vladmihalcea.com
About me
• Java Champion
• vladmihalcea.com
• @vlad_mihalcea
• vladmihalcea
@vlad_mihalcea vladmihalcea.com
InfoQ – Trends Report
https://www.infoq.com/articles/architecture-trends-2019/
@vlad_mihalcea vladmihalcea.com
InfoQ – Trends Report
https://www.infoq.com/articles/architecture-trends-2019/
@vlad_mihalcea vladmihalcea.com
StackOverflow Survey – Most Popular Technologies
https://insights.stackoverflow.com/survey/2019
@vlad_mihalcea vladmihalcea.com
SQL is old school
https://www.pexels.com/photo/antique-blur-classic-close-up-595699/
@vlad_mihalcea vladmihalcea.com
SQL – ‘70s
1970
E.F. Codd’s from IBM
Relational Model
1974
D. D. Chamberlin & R. F. Boyce
IBM System R
1974
Michael Stonebraker
Berkeley Ingres
1979
Relational Software, Inc.
Oracle V2 Marketing
@vlad_mihalcea vladmihalcea.com
SQL – ‘80s
IBM System R
1981
IBM SQL/DS 1983
IBM DB2
1987
IBM DB2 for OS/2
1985
Robert Epstein
Sybase
Berkeley Ingres
1988
Microsoft
Sybase SQL Server
1985
Michael Stonebraker
POSTGRES
@vlad_mihalcea vladmihalcea.com
SQL – ‘90s
1995
David Axmark & Michael Widenius
MySQL
Sybase SQL Server
1993
Microsoft
SQL Server
POSTGRES
1996
PostgreSQL
@vlad_mihalcea vladmihalcea.com
Why is SQL still used?
https://qr.ae/TWCBD5
@vlad_mihalcea vladmihalcea.com
StackOverflow Survey – Most Popular Databases
https://insights.stackoverflow.com/survey/2019
@vlad_mihalcea vladmihalcea.com
StackOverflow Survey – Most Popular Databases
https://insights.stackoverflow.com/survey/2019
@vlad_mihalcea vladmihalcea.com
What does SQL stand for?
S? Query Language
@vlad_mihalcea vladmihalcea.com
What does SQL stand for?
https://twitter.com/vlad_mihalcea/status/1172446336131596289
@vlad_mihalcea vladmihalcea.com
SQL Standard
Photo by Frederick Tubiermont on Unsplash https://unsplash.com/photos/fJSRg-r7LuI
@vlad_mihalcea vladmihalcea.com
SQL:92
@vlad_mihalcea vladmihalcea.com
SQL:92
• In 1992, a major version of the standard was released. The
specification grew from 115 pages to 580.
• SQL:92 adds support for:
• DATE, TIME, TIMESTAMP, INTERVAL, BIT, VARCHAR, NVARCHAR,
• UNION, NATURAL JOIN,
• CASE expressions,
• CHECK constraints,
• Type casting (e.g., CAST (expr AS type))
@vlad_mihalcea vladmihalcea.com
SQL:92
• Other SQL:92 features include:
• INFORMATION_SCHEMA,
• Dynamic query execution (e.g., java.sql.Statement). Previously, only
prepared statements were supported.
• Temporary tables,
• Custom isolation levels,
• Database cursors,
• Scalar operations like String concatenation, date manipulation.
@vlad_mihalcea vladmihalcea.com
Fetching one-to-many relationship with pagination
@vlad_mihalcea vladmihalcea.com
Fetching one-to-many relationship with pagination
We need to get the first 2 post entries
starting with a given string value, along
with all their associated post_comment
child records.
@vlad_mihalcea vladmihalcea.com
post
id review post_id
1 SQL:2016 is great! 1
2 SQL:2016 is excellent! 1
3
SQL:20016 is awesome!
1
4 SQL:2011 is great! 2
5 SQL:2011 is excellent! 2
7 SQL:2008 is great! 3
id title
1 SQL:2016
2 SQL:2011
3 SQL:2008
Fetching one-to-many relationship with pagination
post_comment
post_id post_title comment_id comment_review
1 SQL:2016 1 SQL:2016 is great!
1 SQL:2016 2 SQL:2016 is excellent!
1 SQL:2016 3
SQL:20016 is awesome!
Result set
@vlad_mihalcea vladmihalcea.com
post
id review post_id
1 SQL:2016 is great! 1
2 SQL:2016 is excellent! 1
3
SQL:20016 is awesome!
1
4 SQL:2011 is great! 2
5 SQL:2011 is excellent! 2
7 SQL:2008 is great! 3
id title
1 SQL:2016
2 SQL:2011
3 SQL:2008
Fetching one-to-many relationship with pagination
post_comment
post_id post_title comment_id comment_review
1 SQL:2016 1 SQL:2016 is great!
1 SQL:2016 2 SQL:2016 is excellent!
1 SQL:2016 3
SQL:20016 is awesome!
2 SQL:2011 4 SQL:2011 is great!
2 SQL:2011 5 SQL:2011 is excellent!
Result set
@vlad_mihalcea vladmihalcea.com
JPQL – Join fetch with Pagination
List<Post> posts = entityManager
.createQuery(
"""
select p
from Post p
left join fetch p.comments pc
where p.title like :title
order by p.id, pc.id
""", Post.class)
.setParameter("title", "SQL%")
.setMaxResults(2)
.getResultList();
@vlad_mihalcea vladmihalcea.com
JPQL – Join fetch with Pagination
WARN [main]: QueryTranslatorImpl - HHH000104:
firstResult/maxResults specified with collection fetch;
applying in memory!
SELECT
p.id AS id1_0_0_,
p.title AS title3_0_0_,
pc.id AS id1_1_0__,
pc.post_id AS post_id4_1_1_,
pc.review AS review3_1_1_
FROM post p
LEFT OUTER JOIN post_comment pc ON p.id = pc.post_id
WHERE p.title LIKE 'SQL%'
ORDER BY p.id, pc.id
@vlad_mihalcea vladmihalcea.com
SQL – Join fetch with Pagination
SELECT
p.id AS post_id,
p.title AS post_title,
pc.id AS comment_id,
pc.review AS comment_review
FROM post p
LEFT JOIN post_comment pc ON p.id = pc.post_id
WHERE p.id IN (
SELECT id
FROM post
WHERE p.title LIKE 'SQL%'
ORDER BY id
LIMIT 2
)
ORDER BY post_id, comment_id
@vlad_mihalcea vladmihalcea.com
SQL – Derived tables – Oracle Top N
SELECT t.*
FROM (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
) t
WHERE ROWNUM <= 5
ORDER BY ROWNUM
We must sort the result set prior to assigning the
row ranking numbers.
@vlad_mihalcea vladmihalcea.com
SQL – Derived tables – Oracle Top N
SELECT t.*
FROM (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
) t
WHERE ROWNUM <= 5
ORDER BY ROWNUM
The outer query can now limit the result set size.
@vlad_mihalcea vladmihalcea.com
SQL – Derived tables – Oracle Next N
SELECT t2.*
FROM (
SELECT t1.*, ROWNUM AS ROW_NUM
FROM (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
) t1
WHERE ROWNUM <= 10
) t2
WHERE ROW_NUM > 5
ORDER BY ROW_NUM
We must sort the result set prior to assigning the
row ranking numbers.
@vlad_mihalcea vladmihalcea.com
SQL – Derived tables – Oracle Next N
SELECT t2.*
FROM (
SELECT t1.*, ROWNUM AS ROW_NUM
FROM (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
) t1
WHERE ROWNUM <= 10
) t2
WHERE ROW_NUM > 5
ORDER BY ROW_NUM
The following outer query can now limit the result
set size.
@vlad_mihalcea vladmihalcea.com
SQL – Derived tables – Oracle Next N
SELECT t2.*
FROM (
SELECT t1.*, ROWNUM AS ROW_NUM
FROM (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
) t1
WHERE ROWNUM <= 10
) t2
WHERE ROW_NUM > 5
ORDER BY ROW_NUM
The outer-most query can set the offset where we
want to start streaming the result set back to the
DB client.
@vlad_mihalcea vladmihalcea.com
SQL:92
@vlad_mihalcea vladmihalcea.com
SQL Standard timeline
SQL:86 SQL:89 SQL:92
@vlad_mihalcea vladmihalcea.com
SQL Standard timeline
SQL:86 SQL:89 SQL:92 SQL:1999
SQL:2011 SQL:2008 SQL:2006 SQL:2003
SQL:2016
@vlad_mihalcea vladmihalcea.com
SQL:1999
• In 1999, a new major version of the standard was released.
• It added support for:
• Boolean column type,
• WITH CTE (Common Table Expression) queries and WITH RECURSIVE queries
for hierarchic queries,
• ROLLUP, CUBE, GROUPING SETS for GROUP BY,
• Initial support for ARRAY types (e.g., UNNEST)
@vlad_mihalcea vladmihalcea.com
Pyramid of Doom
SELECT t2.*
FROM (
SELECT t1.*, ROWNUM AS ROW_NUM
FROM (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
) t1
WHERE ROWNUM <= 10
) t2
WHERE ROW_NUM > 5
ORDER BY ROW_NUM
@vlad_mihalcea vladmihalcea.com
• Supported databases:
• Oracle 9i R2
• SQL Server 2005
• PostgreSQL 8.4
• MySQL 8.0.1
• MariaDB 10.2.1
CTE (Common Table Expression)
@vlad_mihalcea vladmihalcea.com
SQL – CTE
WITH
p AS (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
),
p_limit AS (
SELECT p.*, ROWNUM AS ROW_NUM
FROM p
WHERE ROWNUM <= 10
)
SELECT title
FROM p_limit
WHERE ROW_NUM > 5
ORDER BY ROWNUM
@vlad_mihalcea vladmihalcea.com
SQL – CTE
WITH
p AS (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
),
p_limit AS (
SELECT p.*, ROWNUM AS ROW_NUM
FROM p
WHERE ROWNUM <= 10
)
SELECT title
FROM p_limit
WHERE ROW_NUM > 5
ORDER BY ROWNUM
@vlad_mihalcea vladmihalcea.com
SQL – CTE
WITH
p AS (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
),
p_limit AS (
SELECT p.*, ROWNUM AS ROW_NUM
FROM p
WHERE ROWNUM <= 10
)
SELECT title
FROM p_limit
WHERE ROW_NUM > 5
ORDER BY ROWNUM
@vlad_mihalcea vladmihalcea.com
Fetching hierarchical data
6 + 2 + 2 + 1 + …
total_score
@vlad_mihalcea vladmihalcea.com
Fetching hierarchical data
@vlad_mihalcea vladmihalcea.com
Fetch the top 3 comment hierarchies by total score
We need to get the top 3 post_comment
hierarchies based on their total
post_comment score.
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching hierarchical data – table records
post_comment
4 = 1 + 2 + 2 + 1
total_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching hierarchical data – table records
post_comment
3 = 1 + 1 + 1
total_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching hierarchical data – table records
post_comment
9 = 1 + 10 - 2
total_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching hierarchical data – table records
post_comment
-5
total_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching hierarchical data – table records
post_comment
0
total_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching all data – application-level sorting
SELECT
id,
parent_id,
review,
created_on,
score
FROM post_comment
WHERE
post_id = 1
post_comment
@vlad_mihalcea vladmihalcea.com
Fetching all data – application-level sorting
Map<Long, PostCommentScore> postCommentScoreMap = postCommentScores
.stream()
.collect(Collectors.toMap(PostCommentScore::getId, Function.identity()));
List<PostCommentScore> postCommentRoots = postCommentScores
.stream()
.filter(pcs -> {
boolean isRoot = pcs.getParentId() == null;
if(!isRoot) {
postCommentScoreMap.get(pcs.getParentId()).addChild(pcs);
}
return isRoot;
})
.sorted(
Comparator.comparing(PostCommentScore::getTotalScore).reversed()
)
.limit(ranking)
.collect(Collectors.toList());
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching hierarchical data – 1st level
SELECT
id,
parent_id,
review,
created_on,
score
FROM post_comment
WHERE
post_id = 1 AND
parent_id IS NULL
Fetch all root-level comments.
post_comment
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching hierarchical data – 2nd level
WITH pc_r AS (
SELECT
id, parent_id, review,
created_on, score
FROM post_comment
WHERE
post_id = 1 AND
parent_id IS NULL
)
SELECT *
FROM pc_r
UNION ALL
SELECT
pc.id, pc.parent_id,
pc.review, pc.created_on,
pc.score
FROM post_comment pc
INNER JOIN pc_r
ON pc_r.id = pc.parent_id
post_comment
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
Fetching hierarchical data – 2nd level
WITH pc_r AS (
SELECT
id, parent_id, review,
created_on, score
FROM post_comment
WHERE
post_id = 1 AND
parent_id IS NULL
)
SELECT *
FROM pc_r
UNION ALL
SELECT
pc.id, pc.parent_id,
pc.review, pc.created_on,
pc.score
FROM post_comment pc
INNER JOIN pc_r
ON pc_r.id = pc.parent_id
post_comment
@vlad_mihalcea vladmihalcea.com
Fetching hierarchical data – Nth level
This approach of merging manually (using
UNION ALL) the result sets of each
individual level is cumbersome and requires
us knowing the number of levels upfront.
@vlad_mihalcea vladmihalcea.com
SQL – Recursive CTE
WITH RECURSIVE
post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS (
)
The result set table built recursively
@vlad_mihalcea vladmihalcea.com
SQL – Recursive CTE
WITH RECURSIVE
post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS (
)
We want to propagate the root_id
to all comments belonging to the
same hierarchy.
@vlad_mihalcea vladmihalcea.com
SQL – Recursive CTE
WITH RECURSIVE
post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS (
SELECT
id, id, post_id, parent_id, review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
)
Anchor member – the 1st level
@vlad_mihalcea vladmihalcea.com
SQL – Recursive CTE
WITH RECURSIVE
post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS (
SELECT
id, id, post_id, parent_id, review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
)
Anchor member – the 1st level
@vlad_mihalcea vladmihalcea.com
SQL – Recursive CTE
WITH RECURSIVE
post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS (
SELECT
id, id, post_id, parent_id, review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id
)
Recursive member – the 2nd to Nth level
@vlad_mihalcea vladmihalcea.com
SQL – Recursive CTE
WITH RECURSIVE
post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS (
SELECT
id, id, post_id, parent_id, review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id
)
Joining the current and previous levels
@vlad_mihalcea vladmihalcea.com
SQL – Recursive CTE
WITH RECURSIVE
post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS (
SELECT
id, id, post_id, parent_id, review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id
)
SELECT
id, parent_id, root_id, review, created_on, score
FROM post_comment_score
Result set projection query
@vlad_mihalcea vladmihalcea.com
Recursive CTE – 1st level
WITH RECURSIVE post_comment_score(
id, root_id, post_id, parent_id,
review, created_on, score)
AS (
SELECT
id, id, post_id, parent_id,
review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id,
pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs
ON pc.parent_id = pcs.id
)
SELECT
id, parent_id, root_id,
review, created_on, score
FROM post_comment_score
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
post_comment
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
Recursive CTE – 1st level
WITH RECURSIVE post_comment_score(
id, root_id, post_id, parent_id,
review, created_on, score)
AS (
SELECT
id, id, post_id, parent_id,
review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id,
pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs
ON pc.parent_id = pcs.id
)
SELECT
id, parent_id, root_id,
review, created_on, score
FROM post_comment_score
post_comment_score
@vlad_mihalcea vladmihalcea.com
Recursive CTE – 2nd level
WITH RECURSIVE post_comment_score(
id, root_id, post_id, parent_id,
review, created_on, score)
AS (
SELECT
id, id, post_id, parent_id,
review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id,
pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs
ON pc.parent_id = pcs.id
)
SELECT
id, parent_id, root_id,
review, created_on, score
FROM post_comment_score
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
post_comment
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
2 1 1 Comment 1.1 2019-10-14 13:23:10 2
3 1 1 Comment 1.2 2019-10-14 15:45:15 2
6 5 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 5 Comment 2.2 2019-10-14 14:45:35 1
9 8 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 8 Comment 3.2 2019-10-17 18:30:50 -2
Recursive CTE – 2nd level
WITH RECURSIVE post_comment_score(
id, root_id, post_id, parent_id,
review, created_on, score)
AS (
SELECT
id, id, post_id, parent_id,
review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id,
pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs
ON pc.parent_id = pcs.id
)
SELECT
id, parent_id, root_id,
review, created_on, score
FROM post_comment_score
post_comment_score
@vlad_mihalcea vladmihalcea.com
Recursive CTE – 3rd level
WITH RECURSIVE post_comment_score(
id, root_id, post_id, parent_id,
review, created_on, score)
AS (
SELECT
id, id, post_id, parent_id,
review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id,
pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs
ON pc.parent_id = pcs.id
)
SELECT
id, parent_id, root_id,
review, created_on, score
FROM post_comment_score
id parent_id review created_on score post_id
1 Comment 1 2019-10-13 12:23:05 1 1
2 1 Comment 1.1 2019-10-14 13:23:10 2 1
3 1 Comment 1.2 2019-10-14 15:45:15 2 1
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1
5 Comment 2 2019-10-13 15:23:25 1 1
6 5 Comment 2.1 2019-10-14 11:23:30 1 1
7 5 Comment 2.2 2019-10-14 14:45:35 1 1
8 Comment 3 2019-10-15 10:15:40 1 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 1
11 Comment 4 2019-10-19 21:43:55 -5 1
12 Comment 5 2019-10-22 23:45:00 0 1
post_comment
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
2 1 1 Comment 1.1 2019-10-14 13:23:10 2
3 1 1 Comment 1.2 2019-10-14 15:45:15 2
6 5 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 5 Comment 2.2 2019-10-14 14:45:35 1
9 8 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 8 Comment 3.2 2019-10-17 18:30:50 -2
4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1
Recursive CTE – 3rd level
WITH RECURSIVE post_comment_score(
id, root_id, post_id, parent_id,
review, created_on, score)
AS (
SELECT
id, id, post_id, parent_id,
review, created_on, score
FROM post_comment
WHERE post_id = 1 AND parent_id IS NULL
UNION ALL
SELECT
pc.id, pcs.root_id, pc.post_id, pc.parent_id,
pc.review, pc.created_on, pc.score
FROM post_comment pc
INNER JOIN post_comment_score pcs
ON pc.parent_id = pcs.id
)
SELECT
id, parent_id, root_id,
review, created_on, score
FROM post_comment_score
post_comment_score
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
2 1 1 Comment 1.1 2019-10-14 13:23:10 2
3 1 1 Comment 1.2 2019-10-14 15:45:15 2
6 5 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 5 Comment 2.2 2019-10-14 14:45:35 1
9 8 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 8 Comment 3.2 2019-10-17 18:30:50 -2
4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1
Why use Recursive CTE? post_comment_score
@vlad_mihalcea vladmihalcea.com
Window Functions
Photo by Numendil on Unsplash https://unsplash.com/photos/sSKNdbv3qNg
@vlad_mihalcea vladmihalcea.com
SQL:2003
• SQL:2003 was a minor version of SQL:1999.
• It added support for:
• Window Functions,
• MERGE statement
• SEQUNCE generator and IDENTITY column type,
• XML column type
@vlad_mihalcea vladmihalcea.com
• Supported databases:
• Oracle 8i
• SQL Server 2005
• PostgreSQL 8.4
• MySQL 8.0.2
• MariaDB 10.2.0
Window Functions
@vlad_mihalcea vladmihalcea.com
Summing up comment scores by root_id
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
2 1 1 Comment 1.1 2019-10-14 13:23:10 2
3 1 1 Comment 1.2 2019-10-14 15:45:15 2
6 5 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 5 Comment 2.2 2019-10-14 14:45:35 1
9 8 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 8 Comment 3.2 2019-10-17 18:30:50 -2
4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1
Summing comment scores – 1st root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
post_comment_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score total_score
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6
2 1 Comment 1.1 2019-10-14 13:23:10 2 6
3 1 Comment 1.2 2019-10-14 15:45:15 2 6
1 Comment 1 2019-10-13 12:23:05 1 6
6 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 Comment 2.2 2019-10-14 14:45:35 1
5 Comment 2 2019-10-13 15:23:25 1
8 Comment 3 2019-10-15 10:15:40 1
9 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 Comment 3.2 2019-10-17 18:30:50 -2
11 Comment 4 2019-10-19 21:43:55 -5
12 Comment 5 2019-10-22 23:45:00 0
Summing comment scores – 1st root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
total_score_comment
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
2 1 1 Comment 1.1 2019-10-14 13:23:10 2
3 1 1 Comment 1.2 2019-10-14 15:45:15 2
6 5 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 5 Comment 2.2 2019-10-14 14:45:35 1
9 8 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 8 Comment 3.2 2019-10-17 18:30:50 -2
4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1
Summing comment scores – 2nd root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
post_comment_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score total_score
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6
2 1 Comment 1.1 2019-10-14 13:23:10 2 6
3 1 Comment 1.2 2019-10-14 15:45:15 2 6
1 Comment 1 2019-10-13 12:23:05 1 6
6 5 Comment 2.1 2019-10-14 11:23:30 1 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3
5 Comment 2 2019-10-13 15:23:25 1 3
8 Comment 3 2019-10-15 10:15:40 1
9 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 Comment 3.2 2019-10-17 18:30:50 -2
11 Comment 4 2019-10-19 21:43:55 -5
12 Comment 5 2019-10-22 23:45:00 0
Summing comment scores – 2nd root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
total_score_comment
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
2 1 1 Comment 1.1 2019-10-14 13:23:10 2
3 1 1 Comment 1.2 2019-10-14 15:45:15 2
6 5 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 5 Comment 2.2 2019-10-14 14:45:35 1
9 8 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 8 Comment 3.2 2019-10-17 18:30:50 -2
4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1
Summing comment scores – 3rd root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
post_comment_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score total_score
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6
2 1 Comment 1.1 2019-10-14 13:23:10 2 6
3 1 Comment 1.2 2019-10-14 15:45:15 2 6
1 Comment 1 2019-10-13 12:23:05 1 6
6 5 Comment 2.1 2019-10-14 11:23:30 1 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3
5 Comment 2 2019-10-13 15:23:25 1 3
8 Comment 3 2019-10-15 10:15:40 1 9
9 8 Comment 3.1 2019-10-16 11:15:45 10 9
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9
11 Comment 4 2019-10-19 21:43:55 -5
12 Comment 5 2019-10-22 23:45:00 0
Summing comment scores – 3rd root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
total_score_comment
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
2 1 1 Comment 1.1 2019-10-14 13:23:10 2
3 1 1 Comment 1.2 2019-10-14 15:45:15 2
6 5 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 5 Comment 2.2 2019-10-14 14:45:35 1
9 8 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 8 Comment 3.2 2019-10-17 18:30:50 -2
4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1
Summing comment scores – 4th root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
post_comment_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score total_score
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6
2 1 Comment 1.1 2019-10-14 13:23:10 2 6
3 1 Comment 1.2 2019-10-14 15:45:15 2 6
1 Comment 1 2019-10-13 12:23:05 1 6
6 5 Comment 2.1 2019-10-14 11:23:30 1 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3
5 Comment 2 2019-10-13 15:23:25 1 3
8 Comment 3 2019-10-15 10:15:40 1 9
9 8 Comment 3.1 2019-10-16 11:15:45 10 9
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9
11 Comment 4 2019-10-19 21:43:55 -5 -5
12 Comment 5 2019-10-22 23:45:00 0
Summing comment scores – 4th root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
total_score_comment
@vlad_mihalcea vladmihalcea.com
id parent_id root_id review created_on score
1 1 Comment 1 2019-10-13 12:23:05 1
5 5 Comment 2 2019-10-13 15:23:25 1
8 8 Comment 3 2019-10-15 10:15:40 1
11 11 Comment 4 2019-10-19 21:43:55 -5
12 12 Comment 5 2019-10-22 23:45:00 0
2 1 1 Comment 1.1 2019-10-14 13:23:10 2
3 1 1 Comment 1.2 2019-10-14 15:45:15 2
6 5 5 Comment 2.1 2019-10-14 11:23:30 1
7 5 5 Comment 2.2 2019-10-14 14:45:35 1
9 8 8 Comment 3.1 2019-10-16 11:15:45 10
10 8 8 Comment 3.2 2019-10-17 18:30:50 -2
4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1
Summing comment scores – 5th root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
post_comment_score
@vlad_mihalcea vladmihalcea.com
id parent_id review created_on score total_score
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6
2 1 Comment 1.1 2019-10-14 13:23:10 2 6
3 1 Comment 1.2 2019-10-14 15:45:15 2 6
1 Comment 1 2019-10-13 12:23:05 1 6
6 5 Comment 2.1 2019-10-14 11:23:30 1 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3
5 Comment 2 2019-10-13 15:23:25 1 3
8 Comment 3 2019-10-15 10:15:40 1 9
9 8 Comment 3.1 2019-10-16 11:15:45 10 9
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9
11 Comment 4 2019-10-19 21:43:55 -5 -5
12 Comment 5 2019-10-22 23:45:00 0 0
Summing comment scores – 5th root
total_score_comment
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
SUM(score) OVER (
PARTITION BY root_id
) AS total_score
FROM post_comment_score
),
total_score_comment
@vlad_mihalcea vladmihalcea.com
Ranking comment total scores
total_score_ranking
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
total_score,
DENSE_RANK() OVER (
ORDER BY total_score DESC
) ranking
FROM total_score_comment
),
@vlad_mihalcea vladmihalcea.com
Ranking comment total scores – 1st rank
total_score_ranking
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
total_score,
DENSE_RANK() OVER (
ORDER BY total_score DESC
) ranking
FROM total_score_comment
),
id parent_id review created_on score total_score
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6
2 1 Comment 1.1 2019-10-14 13:23:10 2 6
3 1 Comment 1.2 2019-10-14 15:45:15 2 6
1 Comment 1 2019-10-13 12:23:05 1 6
6 5 Comment 2.1 2019-10-14 11:23:30 1 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3
5 Comment 2 2019-10-13 15:23:25 1 3
8 Comment 3 2019-10-15 10:15:40 1 9
9 8 Comment 3.1 2019-10-16 11:15:45 10 9
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9
11 Comment 4 2019-10-19 21:43:55 -5 -5
12 Comment 5 2019-10-22 23:45:00 0 0
total_score_comme
nt
@vlad_mihalcea vladmihalcea.com
Ranking comment total scores – 1st rank
total_score_ranking
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
total_score,
DENSE_RANK() OVER (
ORDER BY total_score DESC
) ranking
FROM total_score_comment
),
id parent_id review created_on score total_score ranking
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6
2 1 Comment 1.1 2019-10-14 13:23:10 2 6
3 1 Comment 1.2 2019-10-14 15:45:15 2 6
1 Comment 1 2019-10-13 12:23:05 1 6
6 5 Comment 2.1 2019-10-14 11:23:30 1 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3
5 Comment 2 2019-10-13 15:23:25 1 3
8 Comment 3 2019-10-15 10:15:40 1 9 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1
11 Comment 4 2019-10-19 21:43:55 -5 -5
12 Comment 5 2019-10-22 23:45:00 0 0
total_score_ranking
@vlad_mihalcea vladmihalcea.com
Ranking comment total scores – 2nd rank
total_score_ranking
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
total_score,
DENSE_RANK() OVER (
ORDER BY total_score DESC
) ranking
FROM total_score_comment
),
id parent_id review created_on score total_score ranking
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2
2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2
3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2
1 Comment 1 2019-10-13 12:23:05 1 6 2
6 5 Comment 2.1 2019-10-14 11:23:30 1 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3
5 Comment 2 2019-10-13 15:23:25 1 3
8 Comment 3 2019-10-15 10:15:40 1 9 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1
11 Comment 4 2019-10-19 21:43:55 -5 -5
12 Comment 5 2019-10-22 23:45:00 0 0
total_score_ranking
@vlad_mihalcea vladmihalcea.com
Ranking comment total scores – 3rd rank
total_score_ranking
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
total_score,
DENSE_RANK() OVER (
ORDER BY total_score DESC
) ranking
FROM total_score_comment
),
id parent_id review created_on score total_score ranking
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2
2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2
3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2
1 Comment 1 2019-10-13 12:23:05 1 6 2
6 5 Comment 2.1 2019-10-14 11:23:30 1 3 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3 3
5 Comment 2 2019-10-13 15:23:25 1 3 3
8 Comment 3 2019-10-15 10:15:40 1 9 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1
11 Comment 4 2019-10-19 21:43:55 -5 -5
12 Comment 5 2019-10-22 23:45:00 0 0
total_score_ranking
@vlad_mihalcea vladmihalcea.com
Ranking comment total scores – 4th rank
total_score_ranking
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
total_score,
DENSE_RANK() OVER (
ORDER BY total_score DESC
) ranking
FROM total_score_comment
),
id parent_id review created_on score total_score ranking
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2
2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2
3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2
1 Comment 1 2019-10-13 12:23:05 1 6 2
6 5 Comment 2.1 2019-10-14 11:23:30 1 3 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3 3
5 Comment 2 2019-10-13 15:23:25 1 3 3
8 Comment 3 2019-10-15 10:15:40 1 9 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1
11 Comment 4 2019-10-19 21:43:55 -5 -5
12 Comment 5 2019-10-22 23:45:00 0 0 4
total_score_ranking
@vlad_mihalcea vladmihalcea.com
Ranking comment total scores – 5th rank
total_score_ranking
AS (
SELECT
id,
parent_id,
review,
created_on,
score,
total_score,
DENSE_RANK() OVER (
ORDER BY total_score DESC
) ranking
FROM total_score_comment
),
id parent_id review created_on score total_score ranking
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2
2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2
3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2
1 Comment 1 2019-10-13 12:23:05 1 6 2
6 5 Comment 2.1 2019-10-14 11:23:30 1 3 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3 3
5 Comment 2 2019-10-13 15:23:25 1 3 3
8 Comment 3 2019-10-15 10:15:40 1 9 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1
11 Comment 4 2019-10-19 21:43:55 -5 -5 5
12 Comment 5 2019-10-22 23:45:00 0 0 4
total_score_ranking
@vlad_mihalcea vladmihalcea.com
Filtering by the comment total score
SELECT
id,
parent_id,
review,
created_on,
score,
total_score
FROM total_score_ranking
WHERE
ranking <= 3
ORDER BY
total_score DESC,
id ASC
@vlad_mihalcea vladmihalcea.com
Filtering by the comment total score
SELECT
id,
parent_id,
review,
created_on,
score,
total_score
FROM total_score_ranking
WHERE
ranking <= 3
ORDER BY
total_score DESC,
id ASC
id parent_id review created_on score total_score ranking
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2
2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2
3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2
1 Comment 1 2019-10-13 12:23:05 1 6 2
6 5 Comment 2.1 2019-10-14 11:23:30 1 3 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3 3
5 Comment 2 2019-10-13 15:23:25 1 3 3
8 Comment 3 2019-10-15 10:15:40 1 9 1
9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1
11 Comment 4 2019-10-19 21:43:55 -5 -5 5
12 Comment 5 2019-10-22 23:45:00 0 0 4
total_score_ranking
@vlad_mihalcea vladmihalcea.com
Filtering by the comment total score
SELECT
id,
parent_id,
review,
created_on,
score,
total_score
FROM total_score_ranking
WHERE
ranking <= 3
ORDER BY
total_score DESC,
id ASC
id parent_id review created_on score total_score
8 Comment 3 2019-10-15 10:15:40 1 9
9 8 Comment 3.1 2019-10-16 11:15:45 10 9
10 8 Comment 3.2 2019-10-17 18:30:50 -2 9
1 Comment 1 2019-10-13 12:23:05 1 6
2 1 Comment 1.1 2019-10-14 13:23:10 2 6
3 1 Comment 1.2 2019-10-14 15:45:15 2 6
4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6
5 Comment 2 2019-10-13 15:23:25 1 3
6 5 Comment 2.1 2019-10-14 11:23:30 1 3
7 5 Comment 2.2 2019-10-14 14:45:35 1 3
Result set
@vlad_mihalcea vladmihalcea.com
Application-level vs database processing
20 104 656 2040 4640 15024 34880
0
10
20
30
40
50
60
70
80
90
100
Data set size
Time(ms)
Application-level Recursive CTE
@vlad_mihalcea vladmihalcea.com
SQL:2003
• SQL:2003 was a minor version of SQL:1999.
• It added support for:
• Window Functions,
• MERGE statement
• SEQUNCE generator and IDENTITY column type,
• XML column type
@vlad_mihalcea vladmihalcea.com
• Supported databases:
• Oracle 9i
• SQL Server 2008
• PostgreSQL and MySQL offer non-standard UPSERT alternatives.
MERGE
@vlad_mihalcea vladmihalcea.com
Oracle MERGE – Ignore on constraint violation
MERGE INTO book
USING (SELECT 1 FROM dual) ON (id = 1)
WHEN NOT MATCHED THEN
INSERT (
id,
title,
isbn
)
VALUES (
1,
'High-Performance Java Persistence',
'978-9730228236'
)
@vlad_mihalcea vladmihalcea.com
Oracle MERGE – UPDATE on constraint violation
MERGE INTO book
USING (SELECT 1 FROM dual) ON (id = 1)
WHEN MATCHED THEN
UPDATE SET
title = 'High-Performance Java Persistence, 2nd Edition',
isbn = '978-9730228236'
WHEN NOT MATCHED THEN
INSERT (
id,
title,
isbn
)
VALUES (
1,
'High-Performance Java Persistence',
'978-9730228236'
)
@vlad_mihalcea vladmihalcea.com
SQL:2006
• SQL:2006 added support for:
• XQuery,
• SQL/XML functions (e.g., XMLELEMENT)
@vlad_mihalcea vladmihalcea.com
SQL:2008
• SQL:2008 added support for:
• TRUNCATE TABLE,
• Multiple WHEN clauses in CASE expressions,
• INSTEAD OF database triggers (override INSERT, UPDATE, DELETE),
• XQuery regular expression/pattern matching,
• Derived column list to override a derived table column names,
• Standard pagination using:
• FETCH FIRST N ROWS ONLY
• OFFSET M ROWS
@vlad_mihalcea vladmihalcea.com
SQL – Oracle legacy Top N
SELECT t.*
FROM (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
) t
WHERE ROWNUM <= 5
ORDER BY ROWNUM
@vlad_mihalcea vladmihalcea.com
SQL – Standard Top N
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
FETCH FIRST 5 ROWS ONLY
@vlad_mihalcea vladmihalcea.com
SQL – Oracle legacy Next N
SELECT t2.*
FROM (
SELECT t1.*, ROWNUM AS ROW_NUM
FROM (
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
) t1
WHERE ROWNUM <= 10
) t2
WHERE ROW_NUM > 5
ORDER BY ROW_NUM
@vlad_mihalcea vladmihalcea.com
SQL – Standard Next N
SELECT title
FROM post
ORDER BY created_on DESC, id DESC
OFFSET 5 ROWS
FETCH NEXT 5 ROWS ONLY
@vlad_mihalcea vladmihalcea.com
SQL:2011
• SQL: 2011 added support for
• Temporal database,
• System-versioned tables
@vlad_mihalcea vladmihalcea.com
SQL:2016
• SQL: 2016 added support for:
• JSON,
• MATCH_RECOGNIZE (Row Pattern Recognition),
• LISTAGG (aggregate multiple values to a delimited string value),
• DECFLOAT column type (e.g., decimal floating arithmetic),
• Date and Time formatting (e.g., CAST(.. AS .. FORMAT ..),
EXTRACT(.. FROM <datetime>))
@vlad_mihalcea vladmihalcea.com
• Supported databases:
• Oracle 12c
• SQL Server 2016
• PostgreSQL 9.2
• MySQL 5.6
• PostgreSQL and MySQL offer non-standard alternatives.
JSON
@vlad_mihalcea vladmihalcea.com
MySQL – storing JSON
CREATE TABLE book (
id bigint NOT NULL PRIMARY KEY,
isbn VARCHAR(15),
properties JSON
)
@vlad_mihalcea vladmihalcea.com
MySQL – Get scalar attribute
SELECT
id,
CAST(
properties -> '$.price'
AS DECIMAL(4, 2)
) AS price
FROM book
WHERE
properties -> '$.title' = 'High-Performance Java Persistence'
Without casting to DECIMAL, the result will be
returned as a String.
@vlad_mihalcea vladmihalcea.com
MySQL – Get scalar attribute
id isbn properties
1 978-9730228236
{
"title":"High-Performance Java Persistence",
"author":"Vlad Mihalcea",
"publisher":"Amazon",
"price":44.99,
"reviews":[
…
]
}
book
SELECT
id,
CAST(
properties -> '$.price'
AS DECIMAL(4, 2)
) AS price
FROM book
WHERE
properties -> '$.title' =
'High-Performance Java Persistence'
id price
1 44.99 Result set
@vlad_mihalcea vladmihalcea.com
SELECT
id,
properties -> '$.reviews' AS reviews
FROM book
WHERE
isbn = '978-9730228236'
MySQL – Get JSON object
@vlad_mihalcea vladmihalcea.com
MySQL – Get JSON object
SELECT
id,
properties -> '$.reviews' AS reviews
FROM book
WHERE
isbn = '978-9730228236'
id isbn properties
1 978-9730228236
{
"title":"High-Performance Java Persistence",
"author":"Vlad Mihalcea",
"publisher":"Amazon",
"price":44.99,
"reviews":[
{
"reviewer":"Cristiano",
"review":"Excellent book to understand Java Persistence",
"date":"2017-11-14",
"rating":5
},
{
"reviewer":"T.W",
"review":"The best JPA ORM book out there",
"date":"2019-01-27",
"rating":5
},
{
"reviewer":"Shaikh",
"review":"The most informative book",
"date":"2016-12-24",
"rating":4
}
]
}
book
id reviews
1
[
{..},
{..},
{..}
] Result set
@vlad_mihalcea vladmihalcea.com
SELECT r.*
FROM
book,
JSON_TABLE(
properties,
'$.reviews[*]'
COLUMNS(
reviewer VARCHAR(4000) PATH '$.reviewer',
review VARCHAR(4000) PATH '$.review',
review_date DATETIME PATH '$.date’,
rating INT PATH '$.rating'
)
) AS r
WHERE isbn = '978-9730228236'
MySQL – JSON to SQL table
@vlad_mihalcea vladmihalcea.com
SELECT r.*
FROM
book, JSON_TABLE(
properties,
'$.reviews[*]'
COLUMNS(
reviewer VARCHAR(4000) PATH '$.reviewer',
review VARCHAR(4000) PATH '$.review',
review_date DATETIME PATH '$.date’,
rating INT PATH '$.rating'
)
) AS r
WHERE isbn = '978-9730228236'
MySQL – JSON to SQL table
"reviews":[
{
"reviewer":"Cristiano",
"review":"Excellent book to understand Java Persistence",
"date":"2017-11-14",
"rating":5
},
{
"reviewer":"T.W",
"review":"The best JPA ORM book out there",
"date":"2019-01-27",
"rating":5
},
{
"reviewer":"Shaikh",
"review":"The most informative book",
"date":"2016-12-24",
"rating":4
}
]
reviewer review review_date rating
book
@vlad_mihalcea vladmihalcea.com
SELECT r.*
FROM
book, JSON_TABLE(
properties,
'$.reviews[*]'
COLUMNS(
reviewer VARCHAR(4000) PATH '$.reviewer',
review VARCHAR(4000) PATH '$.review',
review_date DATETIME PATH '$.date’,
rating INT PATH '$.rating'
)
) AS r
WHERE isbn = '978-9730228236'
MySQL – JSON to SQL table
"reviews":[
{
"reviewer":"Cristiano",
"review":"Excellent book to understand Java Persistence",
"date":"2017-11-14",
"rating":5
},
{
"reviewer":"T.W",
"review":"The best JPA ORM book out there",
"date":"2019-01-27",
"rating":5
},
{
"reviewer":"Shaikh",
"review":"The most informative book",
"date":"2016-12-24",
"rating":4
}
]
reviewer review review_date rating
Cristiano
Excellent book to understand Java
Persistence
14-Nov-2017 5
book
@vlad_mihalcea vladmihalcea.com
SELECT r.*
FROM
book, JSON_TABLE(
properties,
'$.reviews[*]'
COLUMNS(
reviewer VARCHAR(4000) PATH '$.reviewer',
review VARCHAR(4000) PATH '$.review',
review_date DATETIME PATH '$.date’,
rating INT PATH '$.rating'
)
) AS r
WHERE isbn = '978-9730228236'
MySQL – JSON to SQL table
"reviews":[
{
"reviewer":"Cristiano",
"review":"Excellent book to understand Java Persistence",
"date":"2017-11-14",
"rating":5
},
{
"reviewer":"T.W",
"review":"The best JPA ORM book out there",
"date":"2019-01-27",
"rating":5
},
{
"reviewer":"Shaikh",
"review":"The most informative book",
"date":"2016-12-24",
"rating":4
}
]
reviewer review review_date rating
Cristiano
Excellent book to understand Java
Persistence
14-Nov-2017 5
T.W The best JPA ORM book out there 27-Jan-2019 5
book
@vlad_mihalcea vladmihalcea.com
SELECT r.*
FROM
book, JSON_TABLE(
properties,
'$.reviews[*]'
COLUMNS(
reviewer VARCHAR(4000) PATH '$.reviewer',
review VARCHAR(4000) PATH '$.review',
review_date DATETIME PATH '$.date’,
rating INT PATH '$.rating'
)
) AS r
WHERE isbn = '978-9730228236'
MySQL – JSON to SQL table
"reviews":[
{
"reviewer":"Cristiano",
"review":"Excellent book to understand Java Persistence",
"date":"2017-11-14",
"rating":5
},
{
"reviewer":"T.W",
"review":"The best JPA ORM book out there",
"date":"2019-01-27",
"rating":5
},
{
"reviewer":"Shaikh",
"review":"The most informative book",
"date":"2016-12-24",
"rating":4
}
]
reviewer review review_date rating
Cristiano
Excellent book to understand Java
Persistence
14-Nov-2017 5
T.W The best JPA ORM book out there 27-Jan-2019 5
Shaikh The most informative book 24-Dec-2016 4book
@vlad_mihalcea vladmihalcea.com
SQL timeline
SQL NoSQL NewSQL
1974 2009 2011
@vlad_mihalcea vladmihalcea.com
NewSQL
https://www.pexels.com/photo/architectural-design-architecture-blue-brazil-416998/
@vlad_mihalcea vladmihalcea.com
CockroachDB – SQL support
https://www.cockroachlabs.com/docs/v19.1/sql-statements.html
@vlad_mihalcea vladmihalcea.com
VoltDB – SQL support
https://www.voltdb.com/product/features-benefits/sql-database/
@vlad_mihalcea vladmihalcea.com
VoltDB – SQL support
https://www.voltdb.com/product/features-benefits/sql-database/
@vlad_mihalcea vladmihalcea.com
VoltDB – SQL support
https://www.voltdb.com/product/features-benefits/sql-database/
@vlad_mihalcea vladmihalcea.com
Google BigQuery – SQL support
https://cloud.google.com/bigquery/docs/release-notes#March_23_2016
@vlad_mihalcea vladmihalcea.com
Google Spanner – SQL support
https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/46103.pdf
@vlad_mihalcea vladmihalcea.com
Thank you
• Twitter: @vlad_mihalcea
• Blog: https://vladmihalcea.com/
• Courses: https://vladmihalcea.com/courses/
• Training: https://vladmihalcea.com/trainings/
• Book: https://vladmihalcea.com/books/high-performance-java-persistence/

More Related Content

What's hot

Cloudera Impala Source Code Explanation and Analysis
Cloudera Impala Source Code Explanation and AnalysisCloudera Impala Source Code Explanation and Analysis
Cloudera Impala Source Code Explanation and AnalysisYue Chen
 
ADO.Net Improvements in .Net 2.0
ADO.Net Improvements in .Net 2.0ADO.Net Improvements in .Net 2.0
ADO.Net Improvements in .Net 2.0David Truxall
 
Connect 2016-Move Your XPages Applications to the Fast Lane
Connect 2016-Move Your XPages Applications to the Fast LaneConnect 2016-Move Your XPages Applications to the Fast Lane
Connect 2016-Move Your XPages Applications to the Fast LaneHoward Greenberg
 
OTN TOUR 2016 - DBA Commands and Concepts That Every Developer Should Know
OTN TOUR 2016 - DBA Commands and Concepts That Every Developer Should KnowOTN TOUR 2016 - DBA Commands and Concepts That Every Developer Should Know
OTN TOUR 2016 - DBA Commands and Concepts That Every Developer Should KnowAlex Zaballa
 
In Defense Of Core Data
In Defense Of Core DataIn Defense Of Core Data
In Defense Of Core DataDonny Wals
 
MySQL 5.7 - What's new and How to upgrade
MySQL 5.7 - What's new and How to upgradeMySQL 5.7 - What's new and How to upgrade
MySQL 5.7 - What's new and How to upgradeAbel Flórez
 
Marmagna desai
Marmagna desaiMarmagna desai
Marmagna desaijmsthakur
 
MariaDB Optimizer
MariaDB OptimizerMariaDB Optimizer
MariaDB OptimizerJongJin Lee
 
Advanced MySQL Query Optimizations
Advanced MySQL Query OptimizationsAdvanced MySQL Query Optimizations
Advanced MySQL Query OptimizationsDave Stokes
 
20151010 my sq-landjavav2a
20151010 my sq-landjavav2a20151010 my sq-landjavav2a
20151010 my sq-landjavav2aIvan Ma
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Ontico
 
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and HistogramsDutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and HistogramsDave Stokes
 
Oracle Database Advanced Querying (2016)
Oracle Database Advanced Querying (2016)Oracle Database Advanced Querying (2016)
Oracle Database Advanced Querying (2016)Zohar Elkayam
 
MySQL 8.0 New Features -- September 27th presentation for Open Source Summit
MySQL 8.0 New Features -- September 27th presentation for Open Source SummitMySQL 8.0 New Features -- September 27th presentation for Open Source Summit
MySQL 8.0 New Features -- September 27th presentation for Open Source SummitDave Stokes
 
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...Alex Zaballa
 
Oracle result cache highload 2017
Oracle result cache highload 2017Oracle result cache highload 2017
Oracle result cache highload 2017Alexander Tokarev
 
Enhancements that will make your sql database roar sp1 edition sql bits 2017
Enhancements that will make your sql database roar sp1 edition sql bits 2017Enhancements that will make your sql database roar sp1 edition sql bits 2017
Enhancements that will make your sql database roar sp1 edition sql bits 2017Bob Ward
 
Row level security in enterprise applications
Row level security in enterprise applicationsRow level security in enterprise applications
Row level security in enterprise applicationsAlexander Tokarev
 

What's hot (20)

Postgresql
PostgresqlPostgresql
Postgresql
 
Cloudera Impala Source Code Explanation and Analysis
Cloudera Impala Source Code Explanation and AnalysisCloudera Impala Source Code Explanation and Analysis
Cloudera Impala Source Code Explanation and Analysis
 
ADO.Net Improvements in .Net 2.0
ADO.Net Improvements in .Net 2.0ADO.Net Improvements in .Net 2.0
ADO.Net Improvements in .Net 2.0
 
Connect 2016-Move Your XPages Applications to the Fast Lane
Connect 2016-Move Your XPages Applications to the Fast LaneConnect 2016-Move Your XPages Applications to the Fast Lane
Connect 2016-Move Your XPages Applications to the Fast Lane
 
OTN TOUR 2016 - DBA Commands and Concepts That Every Developer Should Know
OTN TOUR 2016 - DBA Commands and Concepts That Every Developer Should KnowOTN TOUR 2016 - DBA Commands and Concepts That Every Developer Should Know
OTN TOUR 2016 - DBA Commands and Concepts That Every Developer Should Know
 
In Defense Of Core Data
In Defense Of Core DataIn Defense Of Core Data
In Defense Of Core Data
 
MySQL 5.7 - What's new and How to upgrade
MySQL 5.7 - What's new and How to upgradeMySQL 5.7 - What's new and How to upgrade
MySQL 5.7 - What's new and How to upgrade
 
Marmagna desai
Marmagna desaiMarmagna desai
Marmagna desai
 
Cold Hard Cache
Cold Hard CacheCold Hard Cache
Cold Hard Cache
 
MariaDB Optimizer
MariaDB OptimizerMariaDB Optimizer
MariaDB Optimizer
 
Advanced MySQL Query Optimizations
Advanced MySQL Query OptimizationsAdvanced MySQL Query Optimizations
Advanced MySQL Query Optimizations
 
20151010 my sq-landjavav2a
20151010 my sq-landjavav2a20151010 my sq-landjavav2a
20151010 my sq-landjavav2a
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
 
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and HistogramsDutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
 
Oracle Database Advanced Querying (2016)
Oracle Database Advanced Querying (2016)Oracle Database Advanced Querying (2016)
Oracle Database Advanced Querying (2016)
 
MySQL 8.0 New Features -- September 27th presentation for Open Source Summit
MySQL 8.0 New Features -- September 27th presentation for Open Source SummitMySQL 8.0 New Features -- September 27th presentation for Open Source Summit
MySQL 8.0 New Features -- September 27th presentation for Open Source Summit
 
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
 
Oracle result cache highload 2017
Oracle result cache highload 2017Oracle result cache highload 2017
Oracle result cache highload 2017
 
Enhancements that will make your sql database roar sp1 edition sql bits 2017
Enhancements that will make your sql database roar sp1 edition sql bits 2017Enhancements that will make your sql database roar sp1 edition sql bits 2017
Enhancements that will make your sql database roar sp1 edition sql bits 2017
 
Row level security in enterprise applications
Row level security in enterprise applicationsRow level security in enterprise applications
Row level security in enterprise applications
 

Similar to Awesome SQL Tips and Tricks - Voxxed Days Cluj - 2019

How to Implement Distributed Data Store
How to Implement Distributed Data Store How to Implement Distributed Data Store
How to Implement Distributed Data Store Philip Zhong
 
Sql interview prep
Sql interview prepSql interview prep
Sql interview prepssusere339c6
 
Performance tuning
Performance tuningPerformance tuning
Performance tuningami111
 
When to NoSQL and when to know SQL
When to NoSQL and when to know SQLWhen to NoSQL and when to know SQL
When to NoSQL and when to know SQLSimon Elliston Ball
 
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...NoSQLmatters
 
Oracle Database 12c New Features for Developers and DBAs - OTN TOUR LA 2015
Oracle Database 12c  New Features for Developers and DBAs - OTN TOUR LA 2015Oracle Database 12c  New Features for Developers and DBAs - OTN TOUR LA 2015
Oracle Database 12c New Features for Developers and DBAs - OTN TOUR LA 2015Alex Zaballa
 
Dan Hotka's Top 10 Oracle 12c New Features
Dan Hotka's Top 10 Oracle 12c New FeaturesDan Hotka's Top 10 Oracle 12c New Features
Dan Hotka's Top 10 Oracle 12c New FeaturesEmbarcadero Technologies
 
SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)Robert Swisher
 
SQL Tutorial for Marketers
SQL Tutorial for MarketersSQL Tutorial for Marketers
SQL Tutorial for MarketersJustin Mares
 
Migration from mysql to elasticsearch
Migration from mysql to elasticsearchMigration from mysql to elasticsearch
Migration from mysql to elasticsearchRyosuke Nakamura
 
SQL-RISC: New Directions in SQLi Prevention - RSA USA 2013
SQL-RISC: New Directions in SQLi Prevention - RSA USA 2013SQL-RISC: New Directions in SQLi Prevention - RSA USA 2013
SQL-RISC: New Directions in SQLi Prevention - RSA USA 2013Nick Galbreath
 
PostgreSQL - масштабирование в моде, Valentine Gogichashvili (Zalando SE)
PostgreSQL - масштабирование в моде, Valentine Gogichashvili (Zalando SE)PostgreSQL - масштабирование в моде, Valentine Gogichashvili (Zalando SE)
PostgreSQL - масштабирование в моде, Valentine Gogichashvili (Zalando SE)Ontico
 
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...Dave Stokes
 
Database & Technology 2 _ Richard Foote _ 10 things you probably dont know ab...
Database & Technology 2 _ Richard Foote _ 10 things you probably dont know ab...Database & Technology 2 _ Richard Foote _ 10 things you probably dont know ab...
Database & Technology 2 _ Richard Foote _ 10 things you probably dont know ab...InSync2011
 
Ten query tuning techniques every SQL Server programmer should know
Ten query tuning techniques every SQL Server programmer should knowTen query tuning techniques every SQL Server programmer should know
Ten query tuning techniques every SQL Server programmer should knowKevin Kline
 
Sql 2016 - What's New
Sql 2016 - What's NewSql 2016 - What's New
Sql 2016 - What's Newdpcobb
 
SQL server 2016 New Features
SQL server 2016 New FeaturesSQL server 2016 New Features
SQL server 2016 New Featuresaminmesbahi
 

Similar to Awesome SQL Tips and Tricks - Voxxed Days Cluj - 2019 (20)

How to Implement Distributed Data Store
How to Implement Distributed Data Store How to Implement Distributed Data Store
How to Implement Distributed Data Store
 
Sql interview prep
Sql interview prepSql interview prep
Sql interview prep
 
Performance tuning
Performance tuningPerformance tuning
Performance tuning
 
When to NoSQL and when to know SQL
When to NoSQL and when to know SQLWhen to NoSQL and when to know SQL
When to NoSQL and when to know SQL
 
Recursive Query Throwdown
Recursive Query ThrowdownRecursive Query Throwdown
Recursive Query Throwdown
 
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
Simon Elliston Ball – When to NoSQL and When to Know SQL - NoSQL matters Barc...
 
Oracle Database 12c New Features for Developers and DBAs - OTN TOUR LA 2015
Oracle Database 12c  New Features for Developers and DBAs - OTN TOUR LA 2015Oracle Database 12c  New Features for Developers and DBAs - OTN TOUR LA 2015
Oracle Database 12c New Features for Developers and DBAs - OTN TOUR LA 2015
 
Dan Hotka's Top 10 Oracle 12c New Features
Dan Hotka's Top 10 Oracle 12c New FeaturesDan Hotka's Top 10 Oracle 12c New Features
Dan Hotka's Top 10 Oracle 12c New Features
 
SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)
 
Oracle Material.pdf
Oracle Material.pdfOracle Material.pdf
Oracle Material.pdf
 
SQL Tutorial for Marketers
SQL Tutorial for MarketersSQL Tutorial for Marketers
SQL Tutorial for Marketers
 
Migration from mysql to elasticsearch
Migration from mysql to elasticsearchMigration from mysql to elasticsearch
Migration from mysql to elasticsearch
 
SQL-RISC: New Directions in SQLi Prevention - RSA USA 2013
SQL-RISC: New Directions in SQLi Prevention - RSA USA 2013SQL-RISC: New Directions in SQLi Prevention - RSA USA 2013
SQL-RISC: New Directions in SQLi Prevention - RSA USA 2013
 
PostgreSQL - масштабирование в моде, Valentine Gogichashvili (Zalando SE)
PostgreSQL - масштабирование в моде, Valentine Gogichashvili (Zalando SE)PostgreSQL - масштабирование в моде, Valentine Gogichashvili (Zalando SE)
PostgreSQL - масштабирование в моде, Valentine Gogichashvili (Zalando SE)
 
Do You Have the Time
Do You Have the TimeDo You Have the Time
Do You Have the Time
 
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
 
Database & Technology 2 _ Richard Foote _ 10 things you probably dont know ab...
Database & Technology 2 _ Richard Foote _ 10 things you probably dont know ab...Database & Technology 2 _ Richard Foote _ 10 things you probably dont know ab...
Database & Technology 2 _ Richard Foote _ 10 things you probably dont know ab...
 
Ten query tuning techniques every SQL Server programmer should know
Ten query tuning techniques every SQL Server programmer should knowTen query tuning techniques every SQL Server programmer should know
Ten query tuning techniques every SQL Server programmer should know
 
Sql 2016 - What's New
Sql 2016 - What's NewSql 2016 - What's New
Sql 2016 - What's New
 
SQL server 2016 New Features
SQL server 2016 New FeaturesSQL server 2016 New Features
SQL server 2016 New Features
 

Recently uploaded

Statistics, Data Analysis, and Decision Modeling, 5th edition by James R. Eva...
Statistics, Data Analysis, and Decision Modeling, 5th edition by James R. Eva...Statistics, Data Analysis, and Decision Modeling, 5th edition by James R. Eva...
Statistics, Data Analysis, and Decision Modeling, 5th edition by James R. Eva...ssuserf63bd7
 
INTERNSHIP ON PURBASHA COMPOSITE TEX LTD
INTERNSHIP ON PURBASHA COMPOSITE TEX LTDINTERNSHIP ON PURBASHA COMPOSITE TEX LTD
INTERNSHIP ON PURBASHA COMPOSITE TEX LTDRafezzaman
 
detection and classification of knee osteoarthritis.pptx
detection and classification of knee osteoarthritis.pptxdetection and classification of knee osteoarthritis.pptx
detection and classification of knee osteoarthritis.pptxAleenaJamil4
 
Data Analysis Project : Targeting the Right Customers, Presentation on Bank M...
Data Analysis Project : Targeting the Right Customers, Presentation on Bank M...Data Analysis Project : Targeting the Right Customers, Presentation on Bank M...
Data Analysis Project : Targeting the Right Customers, Presentation on Bank M...Boston Institute of Analytics
 
RadioAdProWritingCinderellabyButleri.pdf
RadioAdProWritingCinderellabyButleri.pdfRadioAdProWritingCinderellabyButleri.pdf
RadioAdProWritingCinderellabyButleri.pdfgstagge
 
Predictive Analysis for Loan Default Presentation : Data Analysis Project PPT
Predictive Analysis for Loan Default  Presentation : Data Analysis Project PPTPredictive Analysis for Loan Default  Presentation : Data Analysis Project PPT
Predictive Analysis for Loan Default Presentation : Data Analysis Project PPTBoston Institute of Analytics
 
毕业文凭制作#回国入职#diploma#degree澳洲中央昆士兰大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
毕业文凭制作#回国入职#diploma#degree澳洲中央昆士兰大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree毕业文凭制作#回国入职#diploma#degree澳洲中央昆士兰大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
毕业文凭制作#回国入职#diploma#degree澳洲中央昆士兰大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degreeyuu sss
 
NO1 Certified Black Magic Specialist Expert Amil baba in Lahore Islamabad Raw...
NO1 Certified Black Magic Specialist Expert Amil baba in Lahore Islamabad Raw...NO1 Certified Black Magic Specialist Expert Amil baba in Lahore Islamabad Raw...
NO1 Certified Black Magic Specialist Expert Amil baba in Lahore Islamabad Raw...Amil Baba Dawood bangali
 
办理学位证中佛罗里达大学毕业证,UCF成绩单原版一比一
办理学位证中佛罗里达大学毕业证,UCF成绩单原版一比一办理学位证中佛罗里达大学毕业证,UCF成绩单原版一比一
办理学位证中佛罗里达大学毕业证,UCF成绩单原版一比一F sss
 
LLMs, LMMs, their Improvement Suggestions and the Path towards AGI
LLMs, LMMs, their Improvement Suggestions and the Path towards AGILLMs, LMMs, their Improvement Suggestions and the Path towards AGI
LLMs, LMMs, their Improvement Suggestions and the Path towards AGIThomas Poetter
 
Data Factory in Microsoft Fabric (MsBIP #82)
Data Factory in Microsoft Fabric (MsBIP #82)Data Factory in Microsoft Fabric (MsBIP #82)
Data Factory in Microsoft Fabric (MsBIP #82)Cathrine Wilhelmsen
 
Consent & Privacy Signals on Google *Pixels* - MeasureCamp Amsterdam 2024
Consent & Privacy Signals on Google *Pixels* - MeasureCamp Amsterdam 2024Consent & Privacy Signals on Google *Pixels* - MeasureCamp Amsterdam 2024
Consent & Privacy Signals on Google *Pixels* - MeasureCamp Amsterdam 2024thyngster
 
GA4 Without Cookies [Measure Camp AMS]
GA4 Without Cookies [Measure Camp AMS]GA4 Without Cookies [Measure Camp AMS]
GA4 Without Cookies [Measure Camp AMS]📊 Markus Baersch
 
Easter Eggs From Star Wars and in cars 1 and 2
Easter Eggs From Star Wars and in cars 1 and 2Easter Eggs From Star Wars and in cars 1 and 2
Easter Eggs From Star Wars and in cars 1 and 217djon017
 
RABBIT: A CLI tool for identifying bots based on their GitHub events.
RABBIT: A CLI tool for identifying bots based on their GitHub events.RABBIT: A CLI tool for identifying bots based on their GitHub events.
RABBIT: A CLI tool for identifying bots based on their GitHub events.natarajan8993
 
Decoding the Heart: Student Presentation on Heart Attack Prediction with Data...
Decoding the Heart: Student Presentation on Heart Attack Prediction with Data...Decoding the Heart: Student Presentation on Heart Attack Prediction with Data...
Decoding the Heart: Student Presentation on Heart Attack Prediction with Data...Boston Institute of Analytics
 
专业一比一美国俄亥俄大学毕业证成绩单pdf电子版制作修改
专业一比一美国俄亥俄大学毕业证成绩单pdf电子版制作修改专业一比一美国俄亥俄大学毕业证成绩单pdf电子版制作修改
专业一比一美国俄亥俄大学毕业证成绩单pdf电子版制作修改yuu sss
 
9711147426✨Call In girls Gurgaon Sector 31. SCO 25 escort service
9711147426✨Call In girls Gurgaon Sector 31. SCO 25 escort service9711147426✨Call In girls Gurgaon Sector 31. SCO 25 escort service
9711147426✨Call In girls Gurgaon Sector 31. SCO 25 escort servicejennyeacort
 
原版1:1定制南十字星大学毕业证(SCU毕业证)#文凭成绩单#真实留信学历认证永久存档
原版1:1定制南十字星大学毕业证(SCU毕业证)#文凭成绩单#真实留信学历认证永久存档原版1:1定制南十字星大学毕业证(SCU毕业证)#文凭成绩单#真实留信学历认证永久存档
原版1:1定制南十字星大学毕业证(SCU毕业证)#文凭成绩单#真实留信学历认证永久存档208367051
 

Recently uploaded (20)

Statistics, Data Analysis, and Decision Modeling, 5th edition by James R. Eva...
Statistics, Data Analysis, and Decision Modeling, 5th edition by James R. Eva...Statistics, Data Analysis, and Decision Modeling, 5th edition by James R. Eva...
Statistics, Data Analysis, and Decision Modeling, 5th edition by James R. Eva...
 
INTERNSHIP ON PURBASHA COMPOSITE TEX LTD
INTERNSHIP ON PURBASHA COMPOSITE TEX LTDINTERNSHIP ON PURBASHA COMPOSITE TEX LTD
INTERNSHIP ON PURBASHA COMPOSITE TEX LTD
 
detection and classification of knee osteoarthritis.pptx
detection and classification of knee osteoarthritis.pptxdetection and classification of knee osteoarthritis.pptx
detection and classification of knee osteoarthritis.pptx
 
Data Analysis Project : Targeting the Right Customers, Presentation on Bank M...
Data Analysis Project : Targeting the Right Customers, Presentation on Bank M...Data Analysis Project : Targeting the Right Customers, Presentation on Bank M...
Data Analysis Project : Targeting the Right Customers, Presentation on Bank M...
 
RadioAdProWritingCinderellabyButleri.pdf
RadioAdProWritingCinderellabyButleri.pdfRadioAdProWritingCinderellabyButleri.pdf
RadioAdProWritingCinderellabyButleri.pdf
 
Deep Generative Learning for All - The Gen AI Hype (Spring 2024)
Deep Generative Learning for All - The Gen AI Hype (Spring 2024)Deep Generative Learning for All - The Gen AI Hype (Spring 2024)
Deep Generative Learning for All - The Gen AI Hype (Spring 2024)
 
Predictive Analysis for Loan Default Presentation : Data Analysis Project PPT
Predictive Analysis for Loan Default  Presentation : Data Analysis Project PPTPredictive Analysis for Loan Default  Presentation : Data Analysis Project PPT
Predictive Analysis for Loan Default Presentation : Data Analysis Project PPT
 
毕业文凭制作#回国入职#diploma#degree澳洲中央昆士兰大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
毕业文凭制作#回国入职#diploma#degree澳洲中央昆士兰大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree毕业文凭制作#回国入职#diploma#degree澳洲中央昆士兰大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
毕业文凭制作#回国入职#diploma#degree澳洲中央昆士兰大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
 
NO1 Certified Black Magic Specialist Expert Amil baba in Lahore Islamabad Raw...
NO1 Certified Black Magic Specialist Expert Amil baba in Lahore Islamabad Raw...NO1 Certified Black Magic Specialist Expert Amil baba in Lahore Islamabad Raw...
NO1 Certified Black Magic Specialist Expert Amil baba in Lahore Islamabad Raw...
 
办理学位证中佛罗里达大学毕业证,UCF成绩单原版一比一
办理学位证中佛罗里达大学毕业证,UCF成绩单原版一比一办理学位证中佛罗里达大学毕业证,UCF成绩单原版一比一
办理学位证中佛罗里达大学毕业证,UCF成绩单原版一比一
 
LLMs, LMMs, their Improvement Suggestions and the Path towards AGI
LLMs, LMMs, their Improvement Suggestions and the Path towards AGILLMs, LMMs, their Improvement Suggestions and the Path towards AGI
LLMs, LMMs, their Improvement Suggestions and the Path towards AGI
 
Data Factory in Microsoft Fabric (MsBIP #82)
Data Factory in Microsoft Fabric (MsBIP #82)Data Factory in Microsoft Fabric (MsBIP #82)
Data Factory in Microsoft Fabric (MsBIP #82)
 
Consent & Privacy Signals on Google *Pixels* - MeasureCamp Amsterdam 2024
Consent & Privacy Signals on Google *Pixels* - MeasureCamp Amsterdam 2024Consent & Privacy Signals on Google *Pixels* - MeasureCamp Amsterdam 2024
Consent & Privacy Signals on Google *Pixels* - MeasureCamp Amsterdam 2024
 
GA4 Without Cookies [Measure Camp AMS]
GA4 Without Cookies [Measure Camp AMS]GA4 Without Cookies [Measure Camp AMS]
GA4 Without Cookies [Measure Camp AMS]
 
Easter Eggs From Star Wars and in cars 1 and 2
Easter Eggs From Star Wars and in cars 1 and 2Easter Eggs From Star Wars and in cars 1 and 2
Easter Eggs From Star Wars and in cars 1 and 2
 
RABBIT: A CLI tool for identifying bots based on their GitHub events.
RABBIT: A CLI tool for identifying bots based on their GitHub events.RABBIT: A CLI tool for identifying bots based on their GitHub events.
RABBIT: A CLI tool for identifying bots based on their GitHub events.
 
Decoding the Heart: Student Presentation on Heart Attack Prediction with Data...
Decoding the Heart: Student Presentation on Heart Attack Prediction with Data...Decoding the Heart: Student Presentation on Heart Attack Prediction with Data...
Decoding the Heart: Student Presentation on Heart Attack Prediction with Data...
 
专业一比一美国俄亥俄大学毕业证成绩单pdf电子版制作修改
专业一比一美国俄亥俄大学毕业证成绩单pdf电子版制作修改专业一比一美国俄亥俄大学毕业证成绩单pdf电子版制作修改
专业一比一美国俄亥俄大学毕业证成绩单pdf电子版制作修改
 
9711147426✨Call In girls Gurgaon Sector 31. SCO 25 escort service
9711147426✨Call In girls Gurgaon Sector 31. SCO 25 escort service9711147426✨Call In girls Gurgaon Sector 31. SCO 25 escort service
9711147426✨Call In girls Gurgaon Sector 31. SCO 25 escort service
 
原版1:1定制南十字星大学毕业证(SCU毕业证)#文凭成绩单#真实留信学历认证永久存档
原版1:1定制南十字星大学毕业证(SCU毕业证)#文凭成绩单#真实留信学历认证永久存档原版1:1定制南十字星大学毕业证(SCU毕业证)#文凭成绩单#真实留信学历认证永久存档
原版1:1定制南十字星大学毕业证(SCU毕业证)#文凭成绩单#真实留信学历认证永久存档
 

Awesome SQL Tips and Tricks - Voxxed Days Cluj - 2019

  • 2. @vlad_mihalcea vladmihalcea.com About me • Java Champion • vladmihalcea.com • @vlad_mihalcea • vladmihalcea
  • 3. @vlad_mihalcea vladmihalcea.com InfoQ – Trends Report https://www.infoq.com/articles/architecture-trends-2019/
  • 4. @vlad_mihalcea vladmihalcea.com InfoQ – Trends Report https://www.infoq.com/articles/architecture-trends-2019/
  • 5. @vlad_mihalcea vladmihalcea.com StackOverflow Survey – Most Popular Technologies https://insights.stackoverflow.com/survey/2019
  • 6. @vlad_mihalcea vladmihalcea.com SQL is old school https://www.pexels.com/photo/antique-blur-classic-close-up-595699/
  • 7. @vlad_mihalcea vladmihalcea.com SQL – ‘70s 1970 E.F. Codd’s from IBM Relational Model 1974 D. D. Chamberlin & R. F. Boyce IBM System R 1974 Michael Stonebraker Berkeley Ingres 1979 Relational Software, Inc. Oracle V2 Marketing
  • 8. @vlad_mihalcea vladmihalcea.com SQL – ‘80s IBM System R 1981 IBM SQL/DS 1983 IBM DB2 1987 IBM DB2 for OS/2 1985 Robert Epstein Sybase Berkeley Ingres 1988 Microsoft Sybase SQL Server 1985 Michael Stonebraker POSTGRES
  • 9. @vlad_mihalcea vladmihalcea.com SQL – ‘90s 1995 David Axmark & Michael Widenius MySQL Sybase SQL Server 1993 Microsoft SQL Server POSTGRES 1996 PostgreSQL
  • 10. @vlad_mihalcea vladmihalcea.com Why is SQL still used? https://qr.ae/TWCBD5
  • 11. @vlad_mihalcea vladmihalcea.com StackOverflow Survey – Most Popular Databases https://insights.stackoverflow.com/survey/2019
  • 12. @vlad_mihalcea vladmihalcea.com StackOverflow Survey – Most Popular Databases https://insights.stackoverflow.com/survey/2019
  • 13. @vlad_mihalcea vladmihalcea.com What does SQL stand for? S? Query Language
  • 14. @vlad_mihalcea vladmihalcea.com What does SQL stand for? https://twitter.com/vlad_mihalcea/status/1172446336131596289
  • 15. @vlad_mihalcea vladmihalcea.com SQL Standard Photo by Frederick Tubiermont on Unsplash https://unsplash.com/photos/fJSRg-r7LuI
  • 17. @vlad_mihalcea vladmihalcea.com SQL:92 • In 1992, a major version of the standard was released. The specification grew from 115 pages to 580. • SQL:92 adds support for: • DATE, TIME, TIMESTAMP, INTERVAL, BIT, VARCHAR, NVARCHAR, • UNION, NATURAL JOIN, • CASE expressions, • CHECK constraints, • Type casting (e.g., CAST (expr AS type))
  • 18. @vlad_mihalcea vladmihalcea.com SQL:92 • Other SQL:92 features include: • INFORMATION_SCHEMA, • Dynamic query execution (e.g., java.sql.Statement). Previously, only prepared statements were supported. • Temporary tables, • Custom isolation levels, • Database cursors, • Scalar operations like String concatenation, date manipulation.
  • 20. @vlad_mihalcea vladmihalcea.com Fetching one-to-many relationship with pagination We need to get the first 2 post entries starting with a given string value, along with all their associated post_comment child records.
  • 21. @vlad_mihalcea vladmihalcea.com post id review post_id 1 SQL:2016 is great! 1 2 SQL:2016 is excellent! 1 3 SQL:20016 is awesome! 1 4 SQL:2011 is great! 2 5 SQL:2011 is excellent! 2 7 SQL:2008 is great! 3 id title 1 SQL:2016 2 SQL:2011 3 SQL:2008 Fetching one-to-many relationship with pagination post_comment post_id post_title comment_id comment_review 1 SQL:2016 1 SQL:2016 is great! 1 SQL:2016 2 SQL:2016 is excellent! 1 SQL:2016 3 SQL:20016 is awesome! Result set
  • 22. @vlad_mihalcea vladmihalcea.com post id review post_id 1 SQL:2016 is great! 1 2 SQL:2016 is excellent! 1 3 SQL:20016 is awesome! 1 4 SQL:2011 is great! 2 5 SQL:2011 is excellent! 2 7 SQL:2008 is great! 3 id title 1 SQL:2016 2 SQL:2011 3 SQL:2008 Fetching one-to-many relationship with pagination post_comment post_id post_title comment_id comment_review 1 SQL:2016 1 SQL:2016 is great! 1 SQL:2016 2 SQL:2016 is excellent! 1 SQL:2016 3 SQL:20016 is awesome! 2 SQL:2011 4 SQL:2011 is great! 2 SQL:2011 5 SQL:2011 is excellent! Result set
  • 23. @vlad_mihalcea vladmihalcea.com JPQL – Join fetch with Pagination List<Post> posts = entityManager .createQuery( """ select p from Post p left join fetch p.comments pc where p.title like :title order by p.id, pc.id """, Post.class) .setParameter("title", "SQL%") .setMaxResults(2) .getResultList();
  • 24. @vlad_mihalcea vladmihalcea.com JPQL – Join fetch with Pagination WARN [main]: QueryTranslatorImpl - HHH000104: firstResult/maxResults specified with collection fetch; applying in memory! SELECT p.id AS id1_0_0_, p.title AS title3_0_0_, pc.id AS id1_1_0__, pc.post_id AS post_id4_1_1_, pc.review AS review3_1_1_ FROM post p LEFT OUTER JOIN post_comment pc ON p.id = pc.post_id WHERE p.title LIKE 'SQL%' ORDER BY p.id, pc.id
  • 25. @vlad_mihalcea vladmihalcea.com SQL – Join fetch with Pagination SELECT p.id AS post_id, p.title AS post_title, pc.id AS comment_id, pc.review AS comment_review FROM post p LEFT JOIN post_comment pc ON p.id = pc.post_id WHERE p.id IN ( SELECT id FROM post WHERE p.title LIKE 'SQL%' ORDER BY id LIMIT 2 ) ORDER BY post_id, comment_id
  • 26. @vlad_mihalcea vladmihalcea.com SQL – Derived tables – Oracle Top N SELECT t.* FROM ( SELECT title FROM post ORDER BY created_on DESC, id DESC ) t WHERE ROWNUM <= 5 ORDER BY ROWNUM We must sort the result set prior to assigning the row ranking numbers.
  • 27. @vlad_mihalcea vladmihalcea.com SQL – Derived tables – Oracle Top N SELECT t.* FROM ( SELECT title FROM post ORDER BY created_on DESC, id DESC ) t WHERE ROWNUM <= 5 ORDER BY ROWNUM The outer query can now limit the result set size.
  • 28. @vlad_mihalcea vladmihalcea.com SQL – Derived tables – Oracle Next N SELECT t2.* FROM ( SELECT t1.*, ROWNUM AS ROW_NUM FROM ( SELECT title FROM post ORDER BY created_on DESC, id DESC ) t1 WHERE ROWNUM <= 10 ) t2 WHERE ROW_NUM > 5 ORDER BY ROW_NUM We must sort the result set prior to assigning the row ranking numbers.
  • 29. @vlad_mihalcea vladmihalcea.com SQL – Derived tables – Oracle Next N SELECT t2.* FROM ( SELECT t1.*, ROWNUM AS ROW_NUM FROM ( SELECT title FROM post ORDER BY created_on DESC, id DESC ) t1 WHERE ROWNUM <= 10 ) t2 WHERE ROW_NUM > 5 ORDER BY ROW_NUM The following outer query can now limit the result set size.
  • 30. @vlad_mihalcea vladmihalcea.com SQL – Derived tables – Oracle Next N SELECT t2.* FROM ( SELECT t1.*, ROWNUM AS ROW_NUM FROM ( SELECT title FROM post ORDER BY created_on DESC, id DESC ) t1 WHERE ROWNUM <= 10 ) t2 WHERE ROW_NUM > 5 ORDER BY ROW_NUM The outer-most query can set the offset where we want to start streaming the result set back to the DB client.
  • 32. @vlad_mihalcea vladmihalcea.com SQL Standard timeline SQL:86 SQL:89 SQL:92
  • 33. @vlad_mihalcea vladmihalcea.com SQL Standard timeline SQL:86 SQL:89 SQL:92 SQL:1999 SQL:2011 SQL:2008 SQL:2006 SQL:2003 SQL:2016
  • 34. @vlad_mihalcea vladmihalcea.com SQL:1999 • In 1999, a new major version of the standard was released. • It added support for: • Boolean column type, • WITH CTE (Common Table Expression) queries and WITH RECURSIVE queries for hierarchic queries, • ROLLUP, CUBE, GROUPING SETS for GROUP BY, • Initial support for ARRAY types (e.g., UNNEST)
  • 35. @vlad_mihalcea vladmihalcea.com Pyramid of Doom SELECT t2.* FROM ( SELECT t1.*, ROWNUM AS ROW_NUM FROM ( SELECT title FROM post ORDER BY created_on DESC, id DESC ) t1 WHERE ROWNUM <= 10 ) t2 WHERE ROW_NUM > 5 ORDER BY ROW_NUM
  • 36. @vlad_mihalcea vladmihalcea.com • Supported databases: • Oracle 9i R2 • SQL Server 2005 • PostgreSQL 8.4 • MySQL 8.0.1 • MariaDB 10.2.1 CTE (Common Table Expression)
  • 37. @vlad_mihalcea vladmihalcea.com SQL – CTE WITH p AS ( SELECT title FROM post ORDER BY created_on DESC, id DESC ), p_limit AS ( SELECT p.*, ROWNUM AS ROW_NUM FROM p WHERE ROWNUM <= 10 ) SELECT title FROM p_limit WHERE ROW_NUM > 5 ORDER BY ROWNUM
  • 38. @vlad_mihalcea vladmihalcea.com SQL – CTE WITH p AS ( SELECT title FROM post ORDER BY created_on DESC, id DESC ), p_limit AS ( SELECT p.*, ROWNUM AS ROW_NUM FROM p WHERE ROWNUM <= 10 ) SELECT title FROM p_limit WHERE ROW_NUM > 5 ORDER BY ROWNUM
  • 39. @vlad_mihalcea vladmihalcea.com SQL – CTE WITH p AS ( SELECT title FROM post ORDER BY created_on DESC, id DESC ), p_limit AS ( SELECT p.*, ROWNUM AS ROW_NUM FROM p WHERE ROWNUM <= 10 ) SELECT title FROM p_limit WHERE ROW_NUM > 5 ORDER BY ROWNUM
  • 40. @vlad_mihalcea vladmihalcea.com Fetching hierarchical data 6 + 2 + 2 + 1 + … total_score
  • 42. @vlad_mihalcea vladmihalcea.com Fetch the top 3 comment hierarchies by total score We need to get the top 3 post_comment hierarchies based on their total post_comment score.
  • 43. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching hierarchical data – table records post_comment 4 = 1 + 2 + 2 + 1 total_score
  • 44. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching hierarchical data – table records post_comment 3 = 1 + 1 + 1 total_score
  • 45. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching hierarchical data – table records post_comment 9 = 1 + 10 - 2 total_score
  • 46. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching hierarchical data – table records post_comment -5 total_score
  • 47. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching hierarchical data – table records post_comment 0 total_score
  • 48. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching all data – application-level sorting SELECT id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 post_comment
  • 49. @vlad_mihalcea vladmihalcea.com Fetching all data – application-level sorting Map<Long, PostCommentScore> postCommentScoreMap = postCommentScores .stream() .collect(Collectors.toMap(PostCommentScore::getId, Function.identity())); List<PostCommentScore> postCommentRoots = postCommentScores .stream() .filter(pcs -> { boolean isRoot = pcs.getParentId() == null; if(!isRoot) { postCommentScoreMap.get(pcs.getParentId()).addChild(pcs); } return isRoot; }) .sorted( Comparator.comparing(PostCommentScore::getTotalScore).reversed() ) .limit(ranking) .collect(Collectors.toList());
  • 50. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching hierarchical data – 1st level SELECT id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL Fetch all root-level comments. post_comment
  • 51. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching hierarchical data – 2nd level WITH pc_r AS ( SELECT id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL ) SELECT * FROM pc_r UNION ALL SELECT pc.id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN pc_r ON pc_r.id = pc.parent_id post_comment
  • 52. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 Fetching hierarchical data – 2nd level WITH pc_r AS ( SELECT id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL ) SELECT * FROM pc_r UNION ALL SELECT pc.id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN pc_r ON pc_r.id = pc.parent_id post_comment
  • 53. @vlad_mihalcea vladmihalcea.com Fetching hierarchical data – Nth level This approach of merging manually (using UNION ALL) the result sets of each individual level is cumbersome and requires us knowing the number of levels upfront.
  • 54. @vlad_mihalcea vladmihalcea.com SQL – Recursive CTE WITH RECURSIVE post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS ( ) The result set table built recursively
  • 55. @vlad_mihalcea vladmihalcea.com SQL – Recursive CTE WITH RECURSIVE post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS ( ) We want to propagate the root_id to all comments belonging to the same hierarchy.
  • 56. @vlad_mihalcea vladmihalcea.com SQL – Recursive CTE WITH RECURSIVE post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL ) Anchor member – the 1st level
  • 57. @vlad_mihalcea vladmihalcea.com SQL – Recursive CTE WITH RECURSIVE post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL ) Anchor member – the 1st level
  • 58. @vlad_mihalcea vladmihalcea.com SQL – Recursive CTE WITH RECURSIVE post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) Recursive member – the 2nd to Nth level
  • 59. @vlad_mihalcea vladmihalcea.com SQL – Recursive CTE WITH RECURSIVE post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) Joining the current and previous levels
  • 60. @vlad_mihalcea vladmihalcea.com SQL – Recursive CTE WITH RECURSIVE post_comment_score(id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) SELECT id, parent_id, root_id, review, created_on, score FROM post_comment_score Result set projection query
  • 61. @vlad_mihalcea vladmihalcea.com Recursive CTE – 1st level WITH RECURSIVE post_comment_score( id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) SELECT id, parent_id, root_id, review, created_on, score FROM post_comment_score id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 post_comment
  • 62. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 Recursive CTE – 1st level WITH RECURSIVE post_comment_score( id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) SELECT id, parent_id, root_id, review, created_on, score FROM post_comment_score post_comment_score
  • 63. @vlad_mihalcea vladmihalcea.com Recursive CTE – 2nd level WITH RECURSIVE post_comment_score( id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) SELECT id, parent_id, root_id, review, created_on, score FROM post_comment_score id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 post_comment
  • 64. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 2 1 1 Comment 1.1 2019-10-14 13:23:10 2 3 1 1 Comment 1.2 2019-10-14 15:45:15 2 6 5 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 5 Comment 2.2 2019-10-14 14:45:35 1 9 8 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 8 Comment 3.2 2019-10-17 18:30:50 -2 Recursive CTE – 2nd level WITH RECURSIVE post_comment_score( id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) SELECT id, parent_id, root_id, review, created_on, score FROM post_comment_score post_comment_score
  • 65. @vlad_mihalcea vladmihalcea.com Recursive CTE – 3rd level WITH RECURSIVE post_comment_score( id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) SELECT id, parent_id, root_id, review, created_on, score FROM post_comment_score id parent_id review created_on score post_id 1 Comment 1 2019-10-13 12:23:05 1 1 2 1 Comment 1.1 2019-10-14 13:23:10 2 1 3 1 Comment 1.2 2019-10-14 15:45:15 2 1 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 1 5 Comment 2 2019-10-13 15:23:25 1 1 6 5 Comment 2.1 2019-10-14 11:23:30 1 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 1 8 Comment 3 2019-10-15 10:15:40 1 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 1 11 Comment 4 2019-10-19 21:43:55 -5 1 12 Comment 5 2019-10-22 23:45:00 0 1 post_comment
  • 66. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 2 1 1 Comment 1.1 2019-10-14 13:23:10 2 3 1 1 Comment 1.2 2019-10-14 15:45:15 2 6 5 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 5 Comment 2.2 2019-10-14 14:45:35 1 9 8 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 8 Comment 3.2 2019-10-17 18:30:50 -2 4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1 Recursive CTE – 3rd level WITH RECURSIVE post_comment_score( id, root_id, post_id, parent_id, review, created_on, score) AS ( SELECT id, id, post_id, parent_id, review, created_on, score FROM post_comment WHERE post_id = 1 AND parent_id IS NULL UNION ALL SELECT pc.id, pcs.root_id, pc.post_id, pc.parent_id, pc.review, pc.created_on, pc.score FROM post_comment pc INNER JOIN post_comment_score pcs ON pc.parent_id = pcs.id ) SELECT id, parent_id, root_id, review, created_on, score FROM post_comment_score post_comment_score
  • 67. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 2 1 1 Comment 1.1 2019-10-14 13:23:10 2 3 1 1 Comment 1.2 2019-10-14 15:45:15 2 6 5 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 5 Comment 2.2 2019-10-14 14:45:35 1 9 8 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 8 Comment 3.2 2019-10-17 18:30:50 -2 4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1 Why use Recursive CTE? post_comment_score
  • 68. @vlad_mihalcea vladmihalcea.com Window Functions Photo by Numendil on Unsplash https://unsplash.com/photos/sSKNdbv3qNg
  • 69. @vlad_mihalcea vladmihalcea.com SQL:2003 • SQL:2003 was a minor version of SQL:1999. • It added support for: • Window Functions, • MERGE statement • SEQUNCE generator and IDENTITY column type, • XML column type
  • 70. @vlad_mihalcea vladmihalcea.com • Supported databases: • Oracle 8i • SQL Server 2005 • PostgreSQL 8.4 • MySQL 8.0.2 • MariaDB 10.2.0 Window Functions
  • 71. @vlad_mihalcea vladmihalcea.com Summing up comment scores by root_id total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ),
  • 72. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 2 1 1 Comment 1.1 2019-10-14 13:23:10 2 3 1 1 Comment 1.2 2019-10-14 15:45:15 2 6 5 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 5 Comment 2.2 2019-10-14 14:45:35 1 9 8 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 8 Comment 3.2 2019-10-17 18:30:50 -2 4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1 Summing comment scores – 1st root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), post_comment_score
  • 73. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score total_score 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 1 Comment 1 2019-10-13 12:23:05 1 6 6 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 Comment 2.2 2019-10-14 14:45:35 1 5 Comment 2 2019-10-13 15:23:25 1 8 Comment 3 2019-10-15 10:15:40 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 Comment 3.2 2019-10-17 18:30:50 -2 11 Comment 4 2019-10-19 21:43:55 -5 12 Comment 5 2019-10-22 23:45:00 0 Summing comment scores – 1st root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), total_score_comment
  • 74. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 2 1 1 Comment 1.1 2019-10-14 13:23:10 2 3 1 1 Comment 1.2 2019-10-14 15:45:15 2 6 5 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 5 Comment 2.2 2019-10-14 14:45:35 1 9 8 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 8 Comment 3.2 2019-10-17 18:30:50 -2 4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1 Summing comment scores – 2nd root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), post_comment_score
  • 75. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score total_score 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 1 Comment 1 2019-10-13 12:23:05 1 6 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 5 Comment 2 2019-10-13 15:23:25 1 3 8 Comment 3 2019-10-15 10:15:40 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 Comment 3.2 2019-10-17 18:30:50 -2 11 Comment 4 2019-10-19 21:43:55 -5 12 Comment 5 2019-10-22 23:45:00 0 Summing comment scores – 2nd root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), total_score_comment
  • 76. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 2 1 1 Comment 1.1 2019-10-14 13:23:10 2 3 1 1 Comment 1.2 2019-10-14 15:45:15 2 6 5 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 5 Comment 2.2 2019-10-14 14:45:35 1 9 8 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 8 Comment 3.2 2019-10-17 18:30:50 -2 4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1 Summing comment scores – 3rd root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), post_comment_score
  • 77. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score total_score 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 1 Comment 1 2019-10-13 12:23:05 1 6 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 5 Comment 2 2019-10-13 15:23:25 1 3 8 Comment 3 2019-10-15 10:15:40 1 9 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 11 Comment 4 2019-10-19 21:43:55 -5 12 Comment 5 2019-10-22 23:45:00 0 Summing comment scores – 3rd root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), total_score_comment
  • 78. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 2 1 1 Comment 1.1 2019-10-14 13:23:10 2 3 1 1 Comment 1.2 2019-10-14 15:45:15 2 6 5 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 5 Comment 2.2 2019-10-14 14:45:35 1 9 8 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 8 Comment 3.2 2019-10-17 18:30:50 -2 4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1 Summing comment scores – 4th root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), post_comment_score
  • 79. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score total_score 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 1 Comment 1 2019-10-13 12:23:05 1 6 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 5 Comment 2 2019-10-13 15:23:25 1 3 8 Comment 3 2019-10-15 10:15:40 1 9 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 11 Comment 4 2019-10-19 21:43:55 -5 -5 12 Comment 5 2019-10-22 23:45:00 0 Summing comment scores – 4th root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), total_score_comment
  • 80. @vlad_mihalcea vladmihalcea.com id parent_id root_id review created_on score 1 1 Comment 1 2019-10-13 12:23:05 1 5 5 Comment 2 2019-10-13 15:23:25 1 8 8 Comment 3 2019-10-15 10:15:40 1 11 11 Comment 4 2019-10-19 21:43:55 -5 12 12 Comment 5 2019-10-22 23:45:00 0 2 1 1 Comment 1.1 2019-10-14 13:23:10 2 3 1 1 Comment 1.2 2019-10-14 15:45:15 2 6 5 5 Comment 2.1 2019-10-14 11:23:30 1 7 5 5 Comment 2.2 2019-10-14 14:45:35 1 9 8 8 Comment 3.1 2019-10-16 11:15:45 10 10 8 8 Comment 3.2 2019-10-17 18:30:50 -2 4 3 1 Comment 1.2.1 2019-10-15 10:15:20 1 Summing comment scores – 5th root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), post_comment_score
  • 81. @vlad_mihalcea vladmihalcea.com id parent_id review created_on score total_score 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 1 Comment 1 2019-10-13 12:23:05 1 6 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 5 Comment 2 2019-10-13 15:23:25 1 3 8 Comment 3 2019-10-15 10:15:40 1 9 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 11 Comment 4 2019-10-19 21:43:55 -5 -5 12 Comment 5 2019-10-22 23:45:00 0 0 Summing comment scores – 5th root total_score_comment AS ( SELECT id, parent_id, review, created_on, score, SUM(score) OVER ( PARTITION BY root_id ) AS total_score FROM post_comment_score ), total_score_comment
  • 82. @vlad_mihalcea vladmihalcea.com Ranking comment total scores total_score_ranking AS ( SELECT id, parent_id, review, created_on, score, total_score, DENSE_RANK() OVER ( ORDER BY total_score DESC ) ranking FROM total_score_comment ),
  • 83. @vlad_mihalcea vladmihalcea.com Ranking comment total scores – 1st rank total_score_ranking AS ( SELECT id, parent_id, review, created_on, score, total_score, DENSE_RANK() OVER ( ORDER BY total_score DESC ) ranking FROM total_score_comment ), id parent_id review created_on score total_score 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 1 Comment 1 2019-10-13 12:23:05 1 6 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 5 Comment 2 2019-10-13 15:23:25 1 3 8 Comment 3 2019-10-15 10:15:40 1 9 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 11 Comment 4 2019-10-19 21:43:55 -5 -5 12 Comment 5 2019-10-22 23:45:00 0 0 total_score_comme nt
  • 84. @vlad_mihalcea vladmihalcea.com Ranking comment total scores – 1st rank total_score_ranking AS ( SELECT id, parent_id, review, created_on, score, total_score, DENSE_RANK() OVER ( ORDER BY total_score DESC ) ranking FROM total_score_comment ), id parent_id review created_on score total_score ranking 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 1 Comment 1 2019-10-13 12:23:05 1 6 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 5 Comment 2 2019-10-13 15:23:25 1 3 8 Comment 3 2019-10-15 10:15:40 1 9 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1 11 Comment 4 2019-10-19 21:43:55 -5 -5 12 Comment 5 2019-10-22 23:45:00 0 0 total_score_ranking
  • 85. @vlad_mihalcea vladmihalcea.com Ranking comment total scores – 2nd rank total_score_ranking AS ( SELECT id, parent_id, review, created_on, score, total_score, DENSE_RANK() OVER ( ORDER BY total_score DESC ) ranking FROM total_score_comment ), id parent_id review created_on score total_score ranking 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2 1 Comment 1 2019-10-13 12:23:05 1 6 2 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 5 Comment 2 2019-10-13 15:23:25 1 3 8 Comment 3 2019-10-15 10:15:40 1 9 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1 11 Comment 4 2019-10-19 21:43:55 -5 -5 12 Comment 5 2019-10-22 23:45:00 0 0 total_score_ranking
  • 86. @vlad_mihalcea vladmihalcea.com Ranking comment total scores – 3rd rank total_score_ranking AS ( SELECT id, parent_id, review, created_on, score, total_score, DENSE_RANK() OVER ( ORDER BY total_score DESC ) ranking FROM total_score_comment ), id parent_id review created_on score total_score ranking 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2 1 Comment 1 2019-10-13 12:23:05 1 6 2 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 3 5 Comment 2 2019-10-13 15:23:25 1 3 3 8 Comment 3 2019-10-15 10:15:40 1 9 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1 11 Comment 4 2019-10-19 21:43:55 -5 -5 12 Comment 5 2019-10-22 23:45:00 0 0 total_score_ranking
  • 87. @vlad_mihalcea vladmihalcea.com Ranking comment total scores – 4th rank total_score_ranking AS ( SELECT id, parent_id, review, created_on, score, total_score, DENSE_RANK() OVER ( ORDER BY total_score DESC ) ranking FROM total_score_comment ), id parent_id review created_on score total_score ranking 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2 1 Comment 1 2019-10-13 12:23:05 1 6 2 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 3 5 Comment 2 2019-10-13 15:23:25 1 3 3 8 Comment 3 2019-10-15 10:15:40 1 9 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1 11 Comment 4 2019-10-19 21:43:55 -5 -5 12 Comment 5 2019-10-22 23:45:00 0 0 4 total_score_ranking
  • 88. @vlad_mihalcea vladmihalcea.com Ranking comment total scores – 5th rank total_score_ranking AS ( SELECT id, parent_id, review, created_on, score, total_score, DENSE_RANK() OVER ( ORDER BY total_score DESC ) ranking FROM total_score_comment ), id parent_id review created_on score total_score ranking 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2 1 Comment 1 2019-10-13 12:23:05 1 6 2 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 3 5 Comment 2 2019-10-13 15:23:25 1 3 3 8 Comment 3 2019-10-15 10:15:40 1 9 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1 11 Comment 4 2019-10-19 21:43:55 -5 -5 5 12 Comment 5 2019-10-22 23:45:00 0 0 4 total_score_ranking
  • 89. @vlad_mihalcea vladmihalcea.com Filtering by the comment total score SELECT id, parent_id, review, created_on, score, total_score FROM total_score_ranking WHERE ranking <= 3 ORDER BY total_score DESC, id ASC
  • 90. @vlad_mihalcea vladmihalcea.com Filtering by the comment total score SELECT id, parent_id, review, created_on, score, total_score FROM total_score_ranking WHERE ranking <= 3 ORDER BY total_score DESC, id ASC id parent_id review created_on score total_score ranking 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 2 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 2 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 2 1 Comment 1 2019-10-13 12:23:05 1 6 2 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 3 5 Comment 2 2019-10-13 15:23:25 1 3 3 8 Comment 3 2019-10-15 10:15:40 1 9 1 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 1 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1 11 Comment 4 2019-10-19 21:43:55 -5 -5 5 12 Comment 5 2019-10-22 23:45:00 0 0 4 total_score_ranking
  • 91. @vlad_mihalcea vladmihalcea.com Filtering by the comment total score SELECT id, parent_id, review, created_on, score, total_score FROM total_score_ranking WHERE ranking <= 3 ORDER BY total_score DESC, id ASC id parent_id review created_on score total_score 8 Comment 3 2019-10-15 10:15:40 1 9 9 8 Comment 3.1 2019-10-16 11:15:45 10 9 10 8 Comment 3.2 2019-10-17 18:30:50 -2 9 1 Comment 1 2019-10-13 12:23:05 1 6 2 1 Comment 1.1 2019-10-14 13:23:10 2 6 3 1 Comment 1.2 2019-10-14 15:45:15 2 6 4 3 Comment 1.2.1 2019-10-15 10:15:20 1 6 5 Comment 2 2019-10-13 15:23:25 1 3 6 5 Comment 2.1 2019-10-14 11:23:30 1 3 7 5 Comment 2.2 2019-10-14 14:45:35 1 3 Result set
  • 92. @vlad_mihalcea vladmihalcea.com Application-level vs database processing 20 104 656 2040 4640 15024 34880 0 10 20 30 40 50 60 70 80 90 100 Data set size Time(ms) Application-level Recursive CTE
  • 93. @vlad_mihalcea vladmihalcea.com SQL:2003 • SQL:2003 was a minor version of SQL:1999. • It added support for: • Window Functions, • MERGE statement • SEQUNCE generator and IDENTITY column type, • XML column type
  • 94. @vlad_mihalcea vladmihalcea.com • Supported databases: • Oracle 9i • SQL Server 2008 • PostgreSQL and MySQL offer non-standard UPSERT alternatives. MERGE
  • 95. @vlad_mihalcea vladmihalcea.com Oracle MERGE – Ignore on constraint violation MERGE INTO book USING (SELECT 1 FROM dual) ON (id = 1) WHEN NOT MATCHED THEN INSERT ( id, title, isbn ) VALUES ( 1, 'High-Performance Java Persistence', '978-9730228236' )
  • 96. @vlad_mihalcea vladmihalcea.com Oracle MERGE – UPDATE on constraint violation MERGE INTO book USING (SELECT 1 FROM dual) ON (id = 1) WHEN MATCHED THEN UPDATE SET title = 'High-Performance Java Persistence, 2nd Edition', isbn = '978-9730228236' WHEN NOT MATCHED THEN INSERT ( id, title, isbn ) VALUES ( 1, 'High-Performance Java Persistence', '978-9730228236' )
  • 97. @vlad_mihalcea vladmihalcea.com SQL:2006 • SQL:2006 added support for: • XQuery, • SQL/XML functions (e.g., XMLELEMENT)
  • 98. @vlad_mihalcea vladmihalcea.com SQL:2008 • SQL:2008 added support for: • TRUNCATE TABLE, • Multiple WHEN clauses in CASE expressions, • INSTEAD OF database triggers (override INSERT, UPDATE, DELETE), • XQuery regular expression/pattern matching, • Derived column list to override a derived table column names, • Standard pagination using: • FETCH FIRST N ROWS ONLY • OFFSET M ROWS
  • 99. @vlad_mihalcea vladmihalcea.com SQL – Oracle legacy Top N SELECT t.* FROM ( SELECT title FROM post ORDER BY created_on DESC, id DESC ) t WHERE ROWNUM <= 5 ORDER BY ROWNUM
  • 100. @vlad_mihalcea vladmihalcea.com SQL – Standard Top N SELECT title FROM post ORDER BY created_on DESC, id DESC FETCH FIRST 5 ROWS ONLY
  • 101. @vlad_mihalcea vladmihalcea.com SQL – Oracle legacy Next N SELECT t2.* FROM ( SELECT t1.*, ROWNUM AS ROW_NUM FROM ( SELECT title FROM post ORDER BY created_on DESC, id DESC ) t1 WHERE ROWNUM <= 10 ) t2 WHERE ROW_NUM > 5 ORDER BY ROW_NUM
  • 102. @vlad_mihalcea vladmihalcea.com SQL – Standard Next N SELECT title FROM post ORDER BY created_on DESC, id DESC OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY
  • 103. @vlad_mihalcea vladmihalcea.com SQL:2011 • SQL: 2011 added support for • Temporal database, • System-versioned tables
  • 104. @vlad_mihalcea vladmihalcea.com SQL:2016 • SQL: 2016 added support for: • JSON, • MATCH_RECOGNIZE (Row Pattern Recognition), • LISTAGG (aggregate multiple values to a delimited string value), • DECFLOAT column type (e.g., decimal floating arithmetic), • Date and Time formatting (e.g., CAST(.. AS .. FORMAT ..), EXTRACT(.. FROM <datetime>))
  • 105. @vlad_mihalcea vladmihalcea.com • Supported databases: • Oracle 12c • SQL Server 2016 • PostgreSQL 9.2 • MySQL 5.6 • PostgreSQL and MySQL offer non-standard alternatives. JSON
  • 106. @vlad_mihalcea vladmihalcea.com MySQL – storing JSON CREATE TABLE book ( id bigint NOT NULL PRIMARY KEY, isbn VARCHAR(15), properties JSON )
  • 107. @vlad_mihalcea vladmihalcea.com MySQL – Get scalar attribute SELECT id, CAST( properties -> '$.price' AS DECIMAL(4, 2) ) AS price FROM book WHERE properties -> '$.title' = 'High-Performance Java Persistence' Without casting to DECIMAL, the result will be returned as a String.
  • 108. @vlad_mihalcea vladmihalcea.com MySQL – Get scalar attribute id isbn properties 1 978-9730228236 { "title":"High-Performance Java Persistence", "author":"Vlad Mihalcea", "publisher":"Amazon", "price":44.99, "reviews":[ … ] } book SELECT id, CAST( properties -> '$.price' AS DECIMAL(4, 2) ) AS price FROM book WHERE properties -> '$.title' = 'High-Performance Java Persistence' id price 1 44.99 Result set
  • 109. @vlad_mihalcea vladmihalcea.com SELECT id, properties -> '$.reviews' AS reviews FROM book WHERE isbn = '978-9730228236' MySQL – Get JSON object
  • 110. @vlad_mihalcea vladmihalcea.com MySQL – Get JSON object SELECT id, properties -> '$.reviews' AS reviews FROM book WHERE isbn = '978-9730228236' id isbn properties 1 978-9730228236 { "title":"High-Performance Java Persistence", "author":"Vlad Mihalcea", "publisher":"Amazon", "price":44.99, "reviews":[ { "reviewer":"Cristiano", "review":"Excellent book to understand Java Persistence", "date":"2017-11-14", "rating":5 }, { "reviewer":"T.W", "review":"The best JPA ORM book out there", "date":"2019-01-27", "rating":5 }, { "reviewer":"Shaikh", "review":"The most informative book", "date":"2016-12-24", "rating":4 } ] } book id reviews 1 [ {..}, {..}, {..} ] Result set
  • 111. @vlad_mihalcea vladmihalcea.com SELECT r.* FROM book, JSON_TABLE( properties, '$.reviews[*]' COLUMNS( reviewer VARCHAR(4000) PATH '$.reviewer', review VARCHAR(4000) PATH '$.review', review_date DATETIME PATH '$.date’, rating INT PATH '$.rating' ) ) AS r WHERE isbn = '978-9730228236' MySQL – JSON to SQL table
  • 112. @vlad_mihalcea vladmihalcea.com SELECT r.* FROM book, JSON_TABLE( properties, '$.reviews[*]' COLUMNS( reviewer VARCHAR(4000) PATH '$.reviewer', review VARCHAR(4000) PATH '$.review', review_date DATETIME PATH '$.date’, rating INT PATH '$.rating' ) ) AS r WHERE isbn = '978-9730228236' MySQL – JSON to SQL table "reviews":[ { "reviewer":"Cristiano", "review":"Excellent book to understand Java Persistence", "date":"2017-11-14", "rating":5 }, { "reviewer":"T.W", "review":"The best JPA ORM book out there", "date":"2019-01-27", "rating":5 }, { "reviewer":"Shaikh", "review":"The most informative book", "date":"2016-12-24", "rating":4 } ] reviewer review review_date rating book
  • 113. @vlad_mihalcea vladmihalcea.com SELECT r.* FROM book, JSON_TABLE( properties, '$.reviews[*]' COLUMNS( reviewer VARCHAR(4000) PATH '$.reviewer', review VARCHAR(4000) PATH '$.review', review_date DATETIME PATH '$.date’, rating INT PATH '$.rating' ) ) AS r WHERE isbn = '978-9730228236' MySQL – JSON to SQL table "reviews":[ { "reviewer":"Cristiano", "review":"Excellent book to understand Java Persistence", "date":"2017-11-14", "rating":5 }, { "reviewer":"T.W", "review":"The best JPA ORM book out there", "date":"2019-01-27", "rating":5 }, { "reviewer":"Shaikh", "review":"The most informative book", "date":"2016-12-24", "rating":4 } ] reviewer review review_date rating Cristiano Excellent book to understand Java Persistence 14-Nov-2017 5 book
  • 114. @vlad_mihalcea vladmihalcea.com SELECT r.* FROM book, JSON_TABLE( properties, '$.reviews[*]' COLUMNS( reviewer VARCHAR(4000) PATH '$.reviewer', review VARCHAR(4000) PATH '$.review', review_date DATETIME PATH '$.date’, rating INT PATH '$.rating' ) ) AS r WHERE isbn = '978-9730228236' MySQL – JSON to SQL table "reviews":[ { "reviewer":"Cristiano", "review":"Excellent book to understand Java Persistence", "date":"2017-11-14", "rating":5 }, { "reviewer":"T.W", "review":"The best JPA ORM book out there", "date":"2019-01-27", "rating":5 }, { "reviewer":"Shaikh", "review":"The most informative book", "date":"2016-12-24", "rating":4 } ] reviewer review review_date rating Cristiano Excellent book to understand Java Persistence 14-Nov-2017 5 T.W The best JPA ORM book out there 27-Jan-2019 5 book
  • 115. @vlad_mihalcea vladmihalcea.com SELECT r.* FROM book, JSON_TABLE( properties, '$.reviews[*]' COLUMNS( reviewer VARCHAR(4000) PATH '$.reviewer', review VARCHAR(4000) PATH '$.review', review_date DATETIME PATH '$.date’, rating INT PATH '$.rating' ) ) AS r WHERE isbn = '978-9730228236' MySQL – JSON to SQL table "reviews":[ { "reviewer":"Cristiano", "review":"Excellent book to understand Java Persistence", "date":"2017-11-14", "rating":5 }, { "reviewer":"T.W", "review":"The best JPA ORM book out there", "date":"2019-01-27", "rating":5 }, { "reviewer":"Shaikh", "review":"The most informative book", "date":"2016-12-24", "rating":4 } ] reviewer review review_date rating Cristiano Excellent book to understand Java Persistence 14-Nov-2017 5 T.W The best JPA ORM book out there 27-Jan-2019 5 Shaikh The most informative book 24-Dec-2016 4book
  • 116. @vlad_mihalcea vladmihalcea.com SQL timeline SQL NoSQL NewSQL 1974 2009 2011
  • 118. @vlad_mihalcea vladmihalcea.com CockroachDB – SQL support https://www.cockroachlabs.com/docs/v19.1/sql-statements.html
  • 119. @vlad_mihalcea vladmihalcea.com VoltDB – SQL support https://www.voltdb.com/product/features-benefits/sql-database/
  • 120. @vlad_mihalcea vladmihalcea.com VoltDB – SQL support https://www.voltdb.com/product/features-benefits/sql-database/
  • 121. @vlad_mihalcea vladmihalcea.com VoltDB – SQL support https://www.voltdb.com/product/features-benefits/sql-database/
  • 122. @vlad_mihalcea vladmihalcea.com Google BigQuery – SQL support https://cloud.google.com/bigquery/docs/release-notes#March_23_2016
  • 123. @vlad_mihalcea vladmihalcea.com Google Spanner – SQL support https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/46103.pdf
  • 124. @vlad_mihalcea vladmihalcea.com Thank you • Twitter: @vlad_mihalcea • Blog: https://vladmihalcea.com/ • Courses: https://vladmihalcea.com/courses/ • Training: https://vladmihalcea.com/trainings/ • Book: https://vladmihalcea.com/books/high-performance-java-persistence/