Skip to content

Commit fb310f1

Browse files
committed
doc: Prefer explicit JOIN syntax over old implicit syntax in tutorial
Update src/tutorial/basics.source to match. Author: Jürgen Purtz <[email protected]> Reviewed-by: Thomas Munro <[email protected]> Reviewed-by: "David G. Johnston" <[email protected]> Discussion: https://www.postgresql.org/message-id/flat/[email protected]
1 parent 6b4d23f commit fb310f1

File tree

2 files changed

+43
-53
lines changed

2 files changed

+43
-53
lines changed

doc/src/sgml/query.sgml

+34-40
Original file line numberDiff line numberDiff line change
@@ -440,27 +440,26 @@ SELECT DISTINCT city
440440
Thus far, our queries have only accessed one table at a time.
441441
Queries can access multiple tables at once, or access the same
442442
table in such a way that multiple rows of the table are being
443-
processed at the same time. A query that accesses multiple rows
444-
of the same or different tables at one time is called a
445-
<firstterm>join</firstterm> query. As an example, say you wish to
446-
list all the weather records together with the location of the
447-
associated city. To do that, we need to compare the <structfield>city</structfield>
443+
processed at the same time. Queries that access multiple tables
444+
(or multiple instances of the same table) at one time are called
445+
<firstterm>join</firstterm> queries. They combine rows from one table
446+
with rows from a second table, with an expression specifying which rows
447+
are to be paired. For example, to return all the weather records together
448+
with the location of the associated city, the database needs to compare
449+
the <structfield>city</structfield>
448450
column of each row of the <structname>weather</structname> table with the
449451
<structfield>name</structfield> column of all rows in the <structname>cities</structname>
450-
table, and select the pairs of rows where these values match.
451-
<note>
452+
table, and select the pairs of rows where these values match.<footnote>
452453
<para>
453454
This is only a conceptual model. The join is usually performed
454455
in a more efficient manner than actually comparing each possible
455456
pair of rows, but this is invisible to the user.
456457
</para>
457-
</note>
458+
</footnote>
458459
This would be accomplished by the following query:
459460

460461
<programlisting>
461-
SELECT *
462-
FROM weather, cities
463-
WHERE city = name;
462+
SELECT * FROM weather JOIN cities ON city = name;
464463
</programlisting>
465464

466465
<screen>
@@ -497,23 +496,13 @@ SELECT *
497496
<literal>*</literal>:
498497
<programlisting>
499498
SELECT city, temp_lo, temp_hi, prcp, date, location
500-
FROM weather, cities
501-
WHERE city = name;
499+
FROM weather JOIN cities ON city = name;
502500
</programlisting>
503501
</para>
504502
</listitem>
505503
</itemizedlist>
506504
</para>
507505

508-
<formalpara>
509-
<title>Exercise:</title>
510-
511-
<para>
512-
Attempt to determine the semantics of this query when the
513-
<literal>WHERE</literal> clause is omitted.
514-
</para>
515-
</formalpara>
516-
517506
<para>
518507
Since the columns all had different names, the parser
519508
automatically found which table they belong to. If there
@@ -524,8 +513,7 @@ SELECT city, temp_lo, temp_hi, prcp, date, location
524513
<programlisting>
525514
SELECT weather.city, weather.temp_lo, weather.temp_hi,
526515
weather.prcp, weather.date, cities.location
527-
FROM weather, cities
528-
WHERE cities.name = weather.city;
516+
FROM weather JOIN cities ON weather.city = cities.name;
529517
</programlisting>
530518

531519
It is widely considered good style to qualify all column names
@@ -535,15 +523,24 @@ SELECT weather.city, weather.temp_lo, weather.temp_hi,
535523

536524
<para>
537525
Join queries of the kind seen thus far can also be written in this
538-
alternative form:
526+
form:
539527

540528
<programlisting>
541529
SELECT *
542-
FROM weather INNER JOIN cities ON (weather.city = cities.name);
530+
FROM weather, cities
531+
WHERE city = name;
543532
</programlisting>
544533

545-
This syntax is not as commonly used as the one above, but we show
546-
it here to help you understand the following topics.
534+
This syntax pre-dates the <literal>JOIN</literal>/<literal>ON</literal>
535+
syntax, which was introduced in SQL-92. The tables are simply listed in
536+
the <literal>FROM</literal> clause, and the comparison expression is added
537+
to the <literal>WHERE</literal> clause. The results from this older
538+
implicit syntax and the newer explicit
539+
<literal>JOIN</literal>/<literal>ON</literal> syntax are identical. But
540+
for a reader of the query, the explicit syntax makes its meaning easier to
541+
understand: The join condition is introduced by its own key word whereas
542+
previously the condition was mixed into the <literal>WHERE</literal>
543+
clause together with other conditions.
547544
</para>
548545

549546
<indexterm><primary>join</primary><secondary>outer</secondary></indexterm>
@@ -556,12 +553,12 @@ SELECT *
556553
found we want some <quote>empty values</quote> to be substituted
557554
for the <structname>cities</structname> table's columns. This kind
558555
of query is called an <firstterm>outer join</firstterm>. (The
559-
joins we have seen so far are inner joins.) The command looks
560-
like this:
556+
joins we have seen so far are <firstterm>inner joins</firstterm>.)
557+
The command looks like this:
561558

562559
<programlisting>
563560
SELECT *
564-
FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
561+
FROM weather LEFT OUTER JOIN cities ON weather.city = cities.name;
565562
</programlisting>
566563

567564
<screen>
@@ -591,10 +588,9 @@ SELECT *
591588
</para>
592589
</formalpara>
593590

591+
<indexterm><primary>join</primary><secondary>self</secondary></indexterm>
592+
<indexterm><primary>alias</primary><secondary>for table name in query</secondary></indexterm>
594593
<para>
595-
<indexterm><primary>join</primary><secondary>self</secondary></indexterm>
596-
<indexterm><primary>alias</primary><secondary>for table name in query</secondary></indexterm>
597-
598594
We can also join a table against itself. This is called a
599595
<firstterm>self join</firstterm>. As an example, suppose we wish
600596
to find all the weather records that are in the temperature range
@@ -608,10 +604,9 @@ SELECT *
608604

609605
<programlisting>
610606
SELECT w1.city, w1.temp_lo AS low, w1.temp_hi AS high,
611-
w2.city, w2.temp_lo AS low, w2.temp_hi AS high
612-
FROM weather w1, weather w2
613-
WHERE w1.temp_lo &lt; w2.temp_lo
614-
AND w1.temp_hi &gt; w2.temp_hi;
607+
w2.city, w2.temp_lo AS low, w2.temp_hi AS high
608+
FROM weather w1 JOIN weather w2
609+
ON w1.temp_lo &lt; w2.temp_lo AND w1.temp_hi &gt; w2.temp_hi;
615610
</programlisting>
616611

617612
<screen>
@@ -628,8 +623,7 @@ SELECT w1.city, w1.temp_lo AS low, w1.temp_hi AS high,
628623
queries to save some typing, e.g.:
629624
<programlisting>
630625
SELECT *
631-
FROM weather w, cities c
632-
WHERE w.city = c.name;
626+
FROM weather w JOIN cities c ON w.city = c.name;
633627
</programlisting>
634628
You will encounter this style of abbreviating quite frequently.
635629
</para>

src/tutorial/basics.source

+9-13
Original file line numberDiff line numberDiff line change
@@ -97,42 +97,38 @@ SELECT DISTINCT city
9797

9898
-- The following joins the weather table and the cities table.
9999

100-
SELECT *
101-
FROM weather, cities
102-
WHERE city = name;
100+
SELECT * FROM weather JOIN cities ON city = name;
103101

104102
-- This prevents a duplicate city name column:
105103

106104
SELECT city, temp_lo, temp_hi, prcp, date, location
107-
FROM weather, cities
108-
WHERE city = name;
105+
FROM weather JOIN cities ON city = name;
109106

110107
-- since the column names are all different, we don't have to specify the
111108
-- table name. If you want to be clear, you can do the following. They give
112109
-- identical results, of course.
113110

114111
SELECT weather.city, weather.temp_lo, weather.temp_hi, weather.prcp, weather.date, cities.location
115-
FROM weather, cities
116-
WHERE cities.name = weather.city;
112+
FROM weather JOIN cities ON weather.city = cities.name;
117113

118-
-- JOIN syntax
114+
-- Old join syntax
119115

120116
SELECT *
121-
FROM weather JOIN cities ON (weather.city = cities.name);
117+
FROM weather, cities
118+
WHERE city = name;
122119

123120
-- Outer join
124121

125122
SELECT *
126-
FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
123+
FROM weather LEFT OUTER JOIN cities ON weather.city = cities.name;
127124

128125
-- Suppose we want to find all the records that are in the temperature range
129126
-- of other records. w1 and w2 are aliases for weather.
130127

131128
SELECT w1.city, w1.temp_lo, w1.temp_hi,
132129
w2.city, w2.temp_lo, w2.temp_hi
133-
FROM weather w1, weather w2
134-
WHERE w1.temp_lo < w2.temp_lo
135-
and w1.temp_hi > w2.temp_hi;
130+
FROM weather w1 JOIN weather w2
131+
ON w1.temp_lo < w2.temp_lo AND w1.temp_hi > w2.temp_hi;
136132

137133

138134
-----------------------------

0 commit comments

Comments
 (0)