{"id":53960,"date":"2016-03-18T19:00:08","date_gmt":"2016-03-18T17:00:08","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=53960"},"modified":"2016-03-18T17:21:23","modified_gmt":"2016-03-18T15:21:23","slug":"10-easy-steps-complete-understanding-sql","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html","title":{"rendered":"10 Easy Steps to a Complete Understanding of SQL"},"content":{"rendered":"<p>Too many programmers think SQL is a bit of a beast. It is one of the few <a href=\"https:\/\/en.wikipedia.org\/wiki\/Declarative_programming\"><em>declarative languages<\/em><\/a> out there, and as such, behaves in an entirely different way from imperative, object-oriented, or even functional languages (although, some say that SQL is also <a href=\"http:\/\/thoughts.davisjeff.com\/2011\/09\/25\/sql-the-successful-cousin-of-haskell\/\">somewhat functional<\/a>).<\/p>\n<p>As a SQL trainer (<a href=\"http:\/\/www.jooq.org\/training\">do visit our training, it\u2019s great<\/a>!) I\u2019m writing SQL every day and embracing SQL with our company\u2019s <a title=\"jOOQ is a modern internal DSL modeling typesafe SQL in a fluent Java API with a powerful code generator.\" href=\"http:\/\/www.jooq.org\">Open Source library jOOQ<\/a>.<\/p>\n<p>I thus feel compelled to bring the beauty of SQL a bit closer to those of you still struggling with it. The following tutorial is destined for<\/p>\n<ul>\n<li>readers who have already worked with SQL but never completely understood it<\/li>\n<li>readers who know SQL well but have never really thought about its syntax<\/li>\n<li>readers who want to teach SQL to others<\/li>\n<\/ul>\n<p>This tutorial will focus on SELECT statements only. Other DML statements will be covered in another tutorial.<\/p>\n<p><em>Note: This tutorial was previously published exclusively on <a href=\"http:\/\/tech.pro\">Tech.Pro<\/a> (<a href=\"https:\/\/web.archive.org\/web\/20150312161417\/http:\/\/tech.pro\/tutorial\/1555\/10-easy-steps-to-a-complete-understanding-of-sql\">see a historic version here<\/a>). Unfortunately, Tech.Pro went offline. With the permission of Tech.Pro, we\u2019re re-publishing this content again on the jOOQ blog.<\/em><\/p>\n<p>Here are\u2026<\/p>\n<h2>10 Easy Steps to a Complete Understanding of SQL<\/h2>\n<h3>1. SQL is declarative<\/h3>\n<p>Get this into your head first. Declarative. The only paradigm where you \u201cjust\u201d declare the nature of the results that you would like to get. Not <em>how<\/em> your computer shall compute those results. Isn\u2019t that wonderful?<\/p>\n<pre class=\" brush:sql\">SELECT first_name, last_name \r\nFROM employees \r\nWHERE salary &gt; 100000<\/pre>\n<p>Easy to understand. You don\u2019t care where employee records physically come from. You just want those that have a decent salary.<\/p>\n<h4>What do we learn from this?<\/h4>\n<p>So if this is so simple, what\u2019s the problem? The problem is that most of us intuitively think in terms of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Imperative_programming\"><em>imperative programming<\/em><\/a>. As in: <em>\u201cmachine, do this, and then do that, but before, run a check and fail if this-and-that\u201d<\/em>. This includes storing temporary results in variables, writing loops, iterating, calling functions, etc. etc.<\/p>\n<p>Forget about all that. Think about <em>how to declare<\/em> things. Not about <em>how to tell the machine<\/em> to compute things.<\/p>\n<h3>2. SQL syntax is not \u201cwell-ordered\u201d<\/h3>\n<p>A common source of confusion is the simple fact that SQL syntax elements are not ordered in the way they are executed. The lexical ordering is:<\/p>\n<ul>\n<li>SELECT [ DISTINCT ]<\/li>\n<li>FROM<\/li>\n<li>WHERE<\/li>\n<li>GROUP BY<\/li>\n<li>HAVING<\/li>\n<li>UNION<\/li>\n<li>ORDER BY<\/li>\n<\/ul>\n<p>For simplicity, not all SQL clauses are listed. This lexical ordering differs fundamentally from the logical order (which may again differ from the order of execution, depending on the optimiser choices):<\/p>\n<ul>\n<li>FROM<\/li>\n<li>WHERE<\/li>\n<li>GROUP BY<\/li>\n<li>HAVING<\/li>\n<li>SELECT<\/li>\n<li>DISTINCT<\/li>\n<li>UNION<\/li>\n<li>ORDER BY<\/li>\n<\/ul>\n<p>There are three things to note:<\/p>\n<ol>\n<li>FROM is the first clause, not SELECT. The first thing that happens is loading data from the disk into memory, in order to operate on such data.<\/li>\n<li>SELECT is executed after most other clauses. Most importantly, after FROM and GROUP BY. This is important to understand when you think you can reference stuff that you declare in the SELECT clause from the WHERE clause. The following is not possible:\n<pre class=\" brush:sql\">SELECT A.x + A.y AS z\r\nFROM A\r\nWHERE z = 10 -- z is not available here!<\/pre>\n<p>If you wanted to reuse <code>z<\/code>, you have two options. Either repeat the expression:<\/p>\n<pre class=\" brush:sql\">SELECT A.x + A.y AS z\r\nFROM A\r\nWHERE (A.x + A.y) = 10<\/pre>\n<p>\u2026 or you resort to derived tables, common table expressions, or views to avoid code repetition. See examples further down.<\/li>\n<li>UNION is placed before ORDER BY in both lexical and logical ordering. Many people think that each UNION subselect can be ordered, but according to the SQL standard and most SQL dialects, that is not true. While some dialects allow for ordering <em>subqueries<\/em> or <em>derived tables<\/em>, there is no guarantee that such ordering will be retained after a UNION operation<\/li>\n<\/ol>\n<p>Note, not all databases implement things the same way. Rule number 2, for instance, does not apply exactly in the above way to MySQL, PostgreSQL, and SQLite.<\/p>\n<h4>What do we learn from this?<\/h4>\n<p>Always remember both the <em>lexical order<\/em> and the <em>logical order<\/em> of SQL clauses to avoid very common mistakes. If you understand that distinction, it will become very obvious why some things work and others don\u2019t.<\/p>\n<p>Of course, it would have been nice if the language was designed in a way that the <em>lexical order<\/em> actually reflected the <em>logical order<\/em>, as it is implemented in Microsoft\u2019s <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/vstudio\/bb397926.aspx\">LINQ<\/a>.<\/p>\n<h3>3. SQL is about table references<\/h3>\n<p>Because of the difference between <em>lexical ordering<\/em> and <em>logical ordering<\/em>, most beginners are probably tricked into thinking that column values are the first-class citizens in SQL. They are not. The most important things are table references.<\/p>\n<p>The <a href=\"http:\/\/www.andrew.cmu.edu\/user\/shadow\/sql\/sql1992.txt\">SQL standard<\/a> defines the FROM clause as such:<\/p>\n<pre class=\" brush:sql\">&lt;from clause&gt; ::= \r\n    FROM &lt;table reference&gt; \r\n        [ { &lt;comma&gt; &lt;table reference&gt; }... ]<\/pre>\n<p>The \u201coutput\u201d of the FROM clause is a combined table reference of the combined degree of all table references. Let\u2019s digest this, slowly.<\/p>\n<pre class=\" brush:sql\">FROM a, b<\/pre>\n<p>The above produces a combined table reference of the degree of <code>a<\/code> + the degree of <code>b<\/code>. If <code>a<\/code> has 3 columns and <code>b<\/code> has 5 columns, then the \u201coutput table\u201d will have 8 (<code>3 + 5<\/code>) columns.<\/p>\n<p>The records contained in this combined table reference are those of the cross product \/ cartesian product of <code>a x b<\/code>. In other words, each record of <code>a<\/code> is paired with each record of <code>b<\/code>. If <code>a<\/code> has 3 records and <code>b<\/code> has 5 records, then the above combined table reference will produce 15 records (<code>3 x 5<\/code>).<\/p>\n<p>This \u201coutput\u201d is \u201cfed\u201d \/ \u201cpiped\u201d into the GROUP BY clause (after filtering in the WHERE clause), where it is transformed into a new \u201coutput\u201d. We\u2019ll deal with that later on.<\/p>\n<p>If we\u2019re looking at these things from a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Relational_algebra\"><em>relational algebra<\/em><\/a> \/ <a href=\"http:\/\/en.wikipedia.org\/wiki\/Set_theory\"><em>set theory<\/em><\/a> perspective, a SQL table is a <em>relation<\/em> or a <em>set of tuples<\/em>. And each SQL clause will transform one or several relations in order to produce new relations.<\/p>\n<h4>What do we learn from this?<\/h4>\n<p>Always think in terms of table references to understand how data is \u201cpipelined\u201d through your SQL clauses.<\/p>\n<h3>4. SQL table references can be rather powerful<\/h3>\n<p>A table reference is something rather powerful. A simple example of their power is the JOIN keyword, which is actually not part of the SELECT statement, but part of a \u201cspecial\u201d table reference. The joined table, as defined in the <a href=\"http:\/\/www.andrew.cmu.edu\/user\/shadow\/sql\/sql1992.txt\">SQL standard<\/a> (simplified):<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\" brush:java\">&lt;table reference&gt; ::=\r\n    &lt;table name&gt;\r\n  | &lt;derived table&gt;\r\n  | &lt;joined table&gt;<\/pre>\n<p>If we take again the example from before:<\/p>\n<pre class=\" brush:sql\">FROM a, b<\/pre>\n<p><code>a<\/code> can be a joined table as such:<\/p>\n<pre class=\" brush:java\">a1 JOIN a2 ON a1.id = a2.id<\/pre>\n<p>Expanding this into the previous expression, we\u2019d get:<\/p>\n<pre class=\" brush:sql\">FROM a1 JOIN a2 ON a1.id = a2.id, b<\/pre>\n<p>While it is discouraged to combine the comma-separated list of table references syntax with the joined table syntax, you can most certainly do this. The resulting, combined table reference will now have a degree of <code>a1+a2+b<\/code>.<\/p>\n<p>Derived tables are even more powerful than joined tables. We\u2019ll get to that.<\/p>\n<h4>What do we learn from this?<\/h4>\n<p>Always, always think in terms of table references. Not only is this important to understand how data is \u201cpipelined\u201d through your SQL clauses (see previous section), it will also help you understand how complex table references are constructed.<\/p>\n<p>And, importantly, understand that JOIN is a keyword for constructing joined tables. Not a part of the SELECT statement. Some databases allow for using JOIN in INSERT, UPDATE, DELETE<\/p>\n<h3>5. SQL JOIN tables should be used rather than comma-separated tables<\/h3>\n<p>Before, we\u2019ve seen this clause:<\/p>\n<pre class=\" brush:sql\">FROM a, b<\/pre>\n<p>Advanced SQL developers will probably tell you that it is discouraged to use the comma-separated list at all, and always fully express your JOINs. This will help you improve readability of your SQL statement, and thus prevent mistakes.<\/p>\n<p>One very common mistake is to forget a JOIN predicate somewhere. Think about the following:<\/p>\n<pre class=\" brush:sql\">FROM a, b, c, d, e, f, g, h\r\nWHERE a.a1 = b.bx\r\nAND a.a2 = c.c1\r\nAND d.d1 = b.bc\r\n-- etc...<\/pre>\n<p>The join table syntax is both<\/p>\n<ul>\n<li>Safer, as you can place join predicates close to the joined tables, thus preventing mistakes.<\/li>\n<li>More expressive, as you can distinguish between OUTER JOIN, INNER JOIN, etc.<\/li>\n<\/ul>\n<h4>What do we learn from this?<\/h4>\n<p>Always use JOIN. Never use comma-separated table references in your FROM clauses.<\/p>\n<h3>6. SQL\u2019s different JOIN operations<\/h3>\n<p>JOIN operations essentially come with five flavours:<\/p>\n<ul>\n<li>EQUI JOIN<\/li>\n<li>SEMI JOIN<\/li>\n<li>ANTI JOIN<\/li>\n<li>CROSS JOIN<\/li>\n<li>DIVISION<\/li>\n<\/ul>\n<p>These terms are commonly used in <a href=\"https:\/\/en.wikipedia.org\/wiki\/Relational_algebra\"><em>relational algebra<\/em><\/a>. SQL uses different terms for the above concepts, if they exist at all. Let\u2019s have a closer look:<\/p>\n<h4>EQUI JOIN<\/h4>\n<p>This is the most common JOIN operation. It has two sub-flavours:<\/p>\n<ul>\n<li>INNER JOIN (or just JOIN)<\/li>\n<li>OUTER JOIN (further sub-flavoured as LEFT, RIGHT, FULL OUTER JOIN)<\/li>\n<\/ul>\n<p>The difference is best explained by example:<\/p>\n<pre class=\" brush:java\">-- This table reference contains authors and their books.\r\n-- There is one record for each book and its author.\r\n-- authors without books are NOT included\r\nauthor JOIN book ON author.id = book.author_id\r\n\r\n-- This table reference contains authors and their books\r\n-- There is one record for each book and its author.\r\n-- ... OR there is an \"empty\" record for authors without books\r\n-- (\"empty\" meaning that all book columns are NULL)\r\nauthor LEFT OUTER JOIN book ON author.id = book.author_id<\/pre>\n<h4>SEMI JOIN<\/h4>\n<p>This relational concept can be expressed in two ways in SQL: <a href=\"http:\/\/blog.jooq.org\/2015\/10\/13\/semi-join-and-anti-join-should-have-its-own-syntax-in-sql\/\">Using an IN predicate, or using an EXISTS predicate<\/a>. \u201cSemi\u201d means \u201chalf\u201d in latin. This type of join is used to join only \u201chalf\u201d of a table reference. What does that mean? Consider again the above joining of author and book. Let\u2019s imagine that we don\u2019t want author\/book combinations, but just those authors who actually also have books. Then we can write:<\/p>\n<pre class=\" brush:sql\">-- Using IN\r\nFROM author\r\nWHERE author.id IN (SELECT book.author_id FROM book)\r\n\r\n-- Using EXISTS\r\nFROM author\r\nWHERE EXISTS (SELECT 1 FROM book WHERE book.author_id = author.id)<\/pre>\n<p>While there is no general rule as to whether you should prefer IN or EXISTS, these things can be said:<\/p>\n<ul>\n<li>IN predicates tend to be more readable than EXISTS predicates<\/li>\n<li>EXISTS predicates tend to be more expressive than IN predicates (i.e. it is easier to express very complex SEMI JOIN)<\/li>\n<li>There is no formal difference in performance. There may, however, be a <a href=\"http:\/\/explainextended.com\/2009\/09\/18\/not-in-vs-not-exists-vs-left-join-is-null-mysql\/\">huge performance difference on some databases<\/a>.<\/li>\n<\/ul>\n<p>Because INNER JOIN also produces only those authors that actually have books, many beginners may think that they can then remove duplicates using DISTINCT. They think they can express a SEMI JOIN like this:<\/p>\n<pre class=\" brush:sql\">-- Find only those authors who also have books\r\nSELECT DISTINCT first_name, last_name\r\nFROM author\r\nJOIN book ON author.id = book.author_id<\/pre>\n<p>This is very bad practice for two reasons:<\/p>\n<ul>\n<li>It is very slow, as the database has to load a lot of data into memory, just to remove duplicates again.<\/li>\n<li>It is not entirely correct, even if it produces the correct result in this simple example. But as soon as you JOIN more table references, you will have a very hard time correctly removing duplicates from your results.<\/li>\n<\/ul>\n<p>Some more information about abuse of DISTINCT can be <a href=\"http:\/\/blog.jooq.org\/2013\/07\/30\/10-common-mistakes-java-developers-make-when-writing-sql\/\">seen in this blog post<\/a>.<\/p>\n<h4>ANTI JOIN<\/h4>\n<p>This relational concept is just the opposite of a SEMI JOIN. You can produce it simply by adding a NOT keyword to the IN or EXISTS predicates. An example, where we\u2019ll select those authors who do not have any books:<\/p>\n<pre class=\" brush:sql\">-- Using IN\r\nFROM author\r\nWHERE author.id NOT IN (SELECT book.author_id FROM book)\r\n\r\n-- Using EXISTS\r\nFROM author\r\nWHERE NOT EXISTS (SELECT 1 FROM book WHERE book.author_id = author.id)<\/pre>\n<p>The same rules with respect to performance, readability, expressivity apply. However, there is a small caveat with respect to NULLs when using NOT IN, <a href=\"http:\/\/blog.jooq.org\/2012\/01\/27\/sql-incompatibilities-not-in-and-null-values\/\">which is a bit out of scope for this tutorial<\/a>.<\/p>\n<h4>CROSS JOIN<\/h4>\n<p>This produces a cross product of the two joined table references, combining every record of the first table reference with every record of the second table reference. We have seen before, that this can be achieved with comma-separated table references in the FROM clause. In the rare cases where this is really desired, you can also write a CROSS JOIN explicitly, in most SQL dialects:<\/p>\n<pre class=\" brush:java\">-- Combine every author with every book\r\nauthor CROSS JOIN book<\/pre>\n<h4>DIVISION<\/h4>\n<p>The relational division is really a beast of its own breed. In short, if JOIN is multiplication, division is the inverse of JOIN. Relational divisions are very tough to express in SQL. As this is a beginners\u2019 tutorial, explaining it is out of scope. For the brave among you, <a href=\"http:\/\/blog.jooq.org\/2012\/03\/30\/advanced-sql-relational-division-in-jooq\/\">read on about it here<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Relational_algebra#Division\">here<\/a>, <a href=\"https:\/\/www.simple-talk.com\/sql\/t-sql-programming\/divided-we-stand-the-sql-of-relational-division\/\">and here<\/a>.<\/p>\n<h4>What do we learn from this?<\/h4>\n<p>A lot. Again, let\u2019s hammer this into our heads. SQL is about table references. Joined tables are quite sophisticated table references. But there is a difference in relational-speak and SQL-speak. Not all relational join operations are also formal SQL join operations. With a bit of practice and knowledge about relational theory, you will always be able to choose the right type of relational JOIN and be able to translate it to the correct SQL.<\/p>\n<h3>7. SQL\u2019s derived tables are like table variables<\/h3>\n<p>Before, we\u2019ve learned that SQL is a <em>declarative language<\/em>, and as such, variables do not have a place (they do in some SQL dialects, though). But you can write something <em>like<\/em> variables. And those beasts are called derived tables.<\/p>\n<p>A derived table is nothing but a subquery wrapped in parentheses.<\/p>\n<pre class=\" brush:sql\">-- A derived table\r\nFROM (SELECT * FROM author)<\/pre>\n<p>Note that some SQL dialects require derived tables to have a <em>correlation name<\/em> (also known as alias).<\/p>\n<pre class=\" brush:sql\">-- A derived table with an alias\r\nFROM (SELECT * FROM author) a<\/pre>\n<p>Derived tables are awesome when you want to circumvent the problems caused by the <em>logical ordering<\/em> of SQL clauses. For instance, if you want to reuse a column expression in both the SELECT and the WHERE clause, just write (Oracle dialect):<\/p>\n<pre class=\" brush:sql\">-- Get authors' first and last names, and their age in days\r\nSELECT first_name, last_name, age\r\nFROM (\r\n  SELECT first_name, last_name, current_date - date_of_birth age\r\n  FROM author\r\n)\r\n-- If the age is greater than 10000 days\r\nWHERE age &gt; 10000<\/pre>\n<p>Note that some databases, and the SQL:1999 standard have taken derived tables to the next level, introducing <em>common table expressions<\/em>. This will allow you to reuse the same <em>derived table<\/em> several times within a single SQL SELECT statement. The above query would then translate to the (almost) equivalent:<\/p>\n<pre class=\" brush:sql\">WITH a AS (\r\n  SELECT first_name, last_name, current_date - date_of_birth age\r\n  FROM author\r\n)\r\nSELECT *\r\nFROM a\r\nWHERE age &gt; 10000<\/pre>\n<p>Obviously, you could also externalise \u201ca\u201d into a standalone view for even broader reuse of common SQL subselects. <a href=\"http:\/\/en.wikipedia.org\/wiki\/View_%28SQL%29\">Read more about views here<\/a>.<\/p>\n<h4>What do we learn from this?<\/h4>\n<p>Again, again, again. SQL is mostly about table references, not columns. Make use of them. Don\u2019t be afraid of writing derived tables or other complex table references.<\/p>\n<h3>8. SQL GROUP BY transforms previous table references<\/h3>\n<p>Let\u2019s reconsider our previous FROM clause:<\/p>\n<pre class=\" brush:sql\">FROM a, b<\/pre>\n<p>And now, let\u2019s apply a GROUP BY clause to the above combined table reference<\/p>\n<pre class=\" brush:java\">GROUP BY A.x, A.y, B.z<\/pre>\n<p>The above produces a new table reference with only three remaining columns (!). Let\u2019s digest this again. If you apply GROUP BY, then you reduce the number of available columns in all subsequent logical clauses \u2013 including SELECT. This is the syntactical reason why you can only reference columns from the GROUP BY clause in the SELECT clause.<\/p>\n<ul>\n<li>Note that other columns may still be available as arguments of aggregate functions:\n<pre class=\" brush:sql\">SELECT A.x, A.y, SUM(A.z)\r\nFROM A\r\nGROUP BY A.x, A.y<\/pre>\n<\/li>\n<li>Note that <a href=\"http:\/\/blog.jooq.org\/2012\/08\/05\/mysql-bad-idea-384\/\">MySQL, unfortunately, doesn\u2019t adhere to this standard<\/a>, causing nothing but confusion. Don\u2019t fall for MySQL\u2019s tricks. GROUP BY transforms table references. You can thus only reference columns also referenced in the GROUP BY clause.<\/li>\n<\/ul>\n<h4>What do we learn from this?<\/h4>\n<p>GROUP BY, again, operates on table references, transforming them into a new form.<\/p>\n<h3>9. SQL SELECT is called projection in relational algebra<\/h3>\n<p>I personally like the term \u201cprojection\u201d, as it is used in relational algebra. Once you\u2019ve generated your table reference, filtered it, transformed it, you can step to projecting it to another form. The SELECT clause is like a projector. A table function making use of a <em>row value expression<\/em> to transform each record from the previously constructed table reference into the final outcome.<\/p>\n<p>Within the SELECT clause, you can finally operate on columns, creating complex column expressions as parts of the record \/ row.<\/p>\n<p>There are a lot of special rules with respect to the nature of available expressions, functions, etc. Most importantly, you should remember these:<\/p>\n<ol>\n<li>You can only use column references that can be produced from the \u201coutput\u201d table reference<\/li>\n<li>If you have a GROUP BY clause, you may only reference columns from that clause, or aggregate functions.<\/li>\n<li>You can use window functions instead of aggregate functions, when you don\u2019t have a GROUP BY clause.<\/li>\n<li>If you don\u2019t have a GROUP BY clause, you must not combine aggregate functions with non-aggregate functions.<\/li>\n<li>There are some rules with respect to wrapping regular functions in aggregate functions and vice-versa.<\/li>\n<li>There are \u2026<\/li>\n<\/ol>\n<p>Well, there are lots of complex rules. They could fill yet another tutorial. For instance, the reason why you cannot combine aggregate functions with non-aggregate functions in the projection of a SELECT statement without GROUP BY clause (rule number 4) is this:<\/p>\n<ol>\n<li>It doesn\u2019t make sense. Intuitively.<\/li>\n<li>If intuition doesn\u2019t help (it hardly does, with a SQL beginner), then syntax rules do. SQL:1999 introduced GROUPING SETS, and SQL:2003 introduced empty grouping sets: GROUP BY (). Whenever an aggregate function is present, and there is no explicit GROUP BY clause, an implicit, empty GROUPING SET is applied (rule number 2). Hence, the original rules about <em>logical ordering<\/em> aren\u2019t exactly true anymore, and the projection (SELECT) influences the outcome of a logically preceding, yet lexically succeeding clause (GROUP BY).<\/li>\n<\/ol>\n<p>Confused? Yes. Me too. Let\u2019s get back to simpler things.<\/p>\n<h4>What do we learn from this?<\/h4>\n<p>The SELECT clause may be one of the most complex clauses in SQL, even if it appears so simple. All other clauses just \u201cpipe\u201d table references from one to another. The SELECT clause messes up the beauty of these table references, by completely transforming them, applying some rules to them retroactively.<\/p>\n<p>In order to understand SQL, it is important to understand everything <em>else<\/em> first, before trying to tackle SELECT. Even if SELECT is the first clause in lexical ordering, it should be the last.<\/p>\n<h3>10. SQL DISTINCT, UNION, ORDER BY, and OFFSET are simple again<\/h3>\n<p>After the complicated SELECT, we can get back to simple things again:<\/p>\n<ul>\n<li>Set operations (DISTINCT and UNION)<\/li>\n<li>Ordering operations (ORDER BY, OFFSET .. FETCH)<\/li>\n<\/ul>\n<h4>Set operations<\/h4>\n<p>Set operations operate on \u201csets\u201d, which are actually nothing other than\u2026 tables. Well, almost. Conceptually, they\u2019re easy to understand.<\/p>\n<ul>\n<li>DISTINCT removes duplicates <em>after<\/em> the projection.<\/li>\n<li>UNION concatenates two subselects and removes duplicates<\/li>\n<li>UNION ALL concatenates two subselects retaining duplicates<\/li>\n<li>EXCEPT removes records from the first subselect that are also contained in the second subselect (and then removes duplicates)<\/li>\n<li>INTERSECT retains only records contained in both subselects (and then removes duplicates)<\/li>\n<\/ul>\n<p>All of this removing duplicates is usually non-sense. Most often, you should just use UNION ALL, when you want to concatenate subselects.<\/p>\n<h4>Ordering operations<\/h4>\n<p>Ordering is not a relational feature. It is a SQL-only feature. It is applied at the very end of both <em>lexical ordering<\/em> and <em>logical ordering<\/em> of your SQL statement. Using ORDER BY and OFFSET .. FETCH is the only way to guarantee that records can be accessed by index in a reliable way. All other ordering is always arbitrary and random, even if it may appear to be reproducible.<\/p>\n<p>OFFSET .. FETCH is only one syntax variant. Other variants include MySQL\u2019s and PostgreSQL\u2019s LIMIT .. OFFSET, or SQL Server\u2019s and Sybase\u2019s TOP .. START AT. A good overview of various ways to implement OFFSET .. FETCH <a href=\"http:\/\/www.jooq.org\/doc\/3.1\/manual\/sql-building\/sql-statements\/select-statement\/limit-clause\/\">can be seen here<\/a>.<\/p>\n<h2>Let\u2019s get to work<\/h2>\n<p>As with every language, SQL takes a lot of practice to master. The above 10 simple steps will help you make more sense of the every day SQL that you\u2019re writing. On the other hand, it is also good to learn from common mistakes. The following two articles list lots of common mistakes Java (and other) developers make when writing SQL:<\/p>\n<ul>\n<li><a href=\"http:\/\/blog.jooq.org\/2013\/07\/30\/10-common-mistakes-java-developers-make-when-writing-sql\/\">10 Common Mistakes Java Developers Make when Writing SQL<\/a><\/li>\n<li><a href=\"http:\/\/blog.jooq.org\/2013\/08\/12\/10-more-common-mistakes-java-developers-make-when-writing-sql\/\">10 More Common Mistakes Java Developers Make when Writing SQL<\/a><\/li>\n<li><a href=\"http:\/\/blog.jooq.org\/2014\/05\/26\/yet-another-10-common-mistakes-java-developer-make-when-writing-sql-you-wont-believe-the-last-one\/\">Yet Another 10 Common Mistakes Java Developers Make when Writing SQL<\/a><\/li>\n<\/ul>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/blog.jooq.org\/2016\/03\/17\/10-easy-steps-to-a-complete-understanding-of-sql\/\">10 Easy Steps to a Complete Understanding of SQL<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/join-us\/jcg\/\">JCG partner<\/a> Lukas Eder at the <a href=\"http:\/\/blog.jooq.org\/\">JAVA, SQL, AND JOOQ<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Too many programmers think SQL is a bit of a beast. It is one of the few declarative languages out there, and as such, behaves in an entirely different way from imperative, object-oriented, or even functional languages (although, some say that SQL is also somewhat functional). As a SQL trainer (do visit our training, it\u2019s &hellip;<\/p>\n","protected":false},"author":68,"featured_media":2386,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[244],"class_list":["post-53960","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development","tag-sql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>10 Easy Steps to a Complete Understanding of SQL - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Too many programmers think SQL is a bit of a beast. It is one of the few declarative languages out there, and as such, behaves in an entirely different\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"10 Easy Steps to a Complete Understanding of SQL - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Too many programmers think SQL is a bit of a beast. It is one of the few declarative languages out there, and as such, behaves in an entirely different\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2016-03-18T17:00:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Lukas Eder\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/JavaOOQ\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Eder\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html\"},\"author\":{\"name\":\"Lukas Eder\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/2e5562e68acc527c00dbe1cc618081b2\"},\"headline\":\"10 Easy Steps to a Complete Understanding of SQL\",\"datePublished\":\"2016-03-18T17:00:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html\"},\"wordCount\":3044,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"keywords\":[\"SQL\"],\"articleSection\":[\"Software Development\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html\",\"name\":\"10 Easy Steps to a Complete Understanding of SQL - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"datePublished\":\"2016-03-18T17:00:08+00:00\",\"description\":\"Too many programmers think SQL is a bit of a beast. It is one of the few declarative languages out there, and as such, behaves in an entirely different\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/03\\\/10-easy-steps-complete-understanding-sql.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Software Development\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/software-development\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"10 Easy Steps to a Complete Understanding of SQL\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/2e5562e68acc527c00dbe1cc618081b2\",\"name\":\"Lukas Eder\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0539ed8cbcebfd5df5c2bd3048cf645d90f259da6851a005099b51edfd7a68e1?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0539ed8cbcebfd5df5c2bd3048cf645d90f259da6851a005099b51edfd7a68e1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0539ed8cbcebfd5df5c2bd3048cf645d90f259da6851a005099b51edfd7a68e1?s=96&d=mm&r=g\",\"caption\":\"Lukas Eder\"},\"description\":\"Lukas is a Java and SQL enthusiast developer. He created the Data Geekery GmbH. He is the creator of jOOQ, a comprehensive SQL library for Java, and he is blogging mostly about these three topics: Java, SQL and jOOQ.\",\"sameAs\":[\"http:\\\/\\\/blog.jooq.org\\\/\",\"http:\\\/\\\/www.linkedin.com\\\/profile\\\/view?id=6409824\",\"https:\\\/\\\/x.com\\\/http:\\\/\\\/twitter.com\\\/JavaOOQ\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Lukas-Eder\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"10 Easy Steps to a Complete Understanding of SQL - Java Code Geeks","description":"Too many programmers think SQL is a bit of a beast. It is one of the few declarative languages out there, and as such, behaves in an entirely different","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html","og_locale":"en_US","og_type":"article","og_title":"10 Easy Steps to a Complete Understanding of SQL - Java Code Geeks","og_description":"Too many programmers think SQL is a bit of a beast. It is one of the few declarative languages out there, and as such, behaves in an entirely different","og_url":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2016-03-18T17:00:08+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","type":"image\/jpeg"}],"author":"Lukas Eder","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/JavaOOQ","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Lukas Eder","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html"},"author":{"name":"Lukas Eder","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/2e5562e68acc527c00dbe1cc618081b2"},"headline":"10 Easy Steps to a Complete Understanding of SQL","datePublished":"2016-03-18T17:00:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html"},"wordCount":3044,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","keywords":["SQL"],"articleSection":["Software Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html","url":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html","name":"10 Easy Steps to a Complete Understanding of SQL - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","datePublished":"2016-03-18T17:00:08+00:00","description":"Too many programmers think SQL is a bit of a beast. It is one of the few declarative languages out there, and as such, behaves in an entirely different","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2016\/03\/10-easy-steps-complete-understanding-sql.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Software Development","item":"https:\/\/www.javacodegeeks.com\/category\/software-development"},{"@type":"ListItem","position":3,"name":"10 Easy Steps to a Complete Understanding of SQL"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/2e5562e68acc527c00dbe1cc618081b2","name":"Lukas Eder","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/0539ed8cbcebfd5df5c2bd3048cf645d90f259da6851a005099b51edfd7a68e1?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/0539ed8cbcebfd5df5c2bd3048cf645d90f259da6851a005099b51edfd7a68e1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0539ed8cbcebfd5df5c2bd3048cf645d90f259da6851a005099b51edfd7a68e1?s=96&d=mm&r=g","caption":"Lukas Eder"},"description":"Lukas is a Java and SQL enthusiast developer. He created the Data Geekery GmbH. He is the creator of jOOQ, a comprehensive SQL library for Java, and he is blogging mostly about these three topics: Java, SQL and jOOQ.","sameAs":["http:\/\/blog.jooq.org\/","http:\/\/www.linkedin.com\/profile\/view?id=6409824","https:\/\/x.com\/http:\/\/twitter.com\/JavaOOQ"],"url":"https:\/\/www.javacodegeeks.com\/author\/Lukas-Eder"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/53960","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/68"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=53960"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/53960\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/2386"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=53960"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=53960"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=53960"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}