1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5
>Joins Between Tables</TITLE
8
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
10
HREF="mailto:pgsql-docs@postgresql.org"><LINK
12
TITLE="PostgreSQL 9.1beta1 Documentation"
13
HREF="index.html"><LINK
15
TITLE="The SQL Language"
16
HREF="tutorial-sql.html"><LINK
18
TITLE="Querying a Table"
19
HREF="tutorial-select.html"><LINK
21
TITLE="Aggregate Functions"
22
HREF="tutorial-agg.html"><LINK
25
HREF="stylesheet.css"><META
26
HTTP-EQUIV="Content-Type"
27
CONTENT="text/html; charset=ISO-8859-1"><META
29
CONTENT="2011-04-27T21:20:33"></HEAD
35
SUMMARY="Header navigation table"
47
>PostgreSQL 9.1beta1 Documentation</A
56
TITLE="Querying a Table"
57
HREF="tutorial-select.html"
66
TITLE="The SQL Language"
67
HREF="tutorial-sql.html"
74
>Chapter 2. The <ACRONYM
83
TITLE="The SQL Language"
84
HREF="tutorial-sql.html"
92
TITLE="Aggregate Functions"
93
HREF="tutorial-agg.html"
108
>2.6. Joins Between Tables</A
111
> Thus far, our queries have only accessed one table at a time.
112
Queries can access multiple tables at once, or access the same
113
table in such a way that multiple rows of the table are being
114
processed at the same time. A query that accesses multiple rows
115
of the same or different tables at one time is called a
119
> query. As an example, say you wish to
120
list all the weather records together with the location of the
121
associated city. To do that, we need to compare the <TT
125
column of each row of the <TT
132
> column of all rows in the <TT
136
table, and select the pairs of rows where these values match.
144
> This is only a conceptual model. The join is usually performed
145
in a more efficient manner than actually comparing each possible
146
pair of rows, but this is invisible to the user.
151
This would be accomplished by the following query:
154
CLASS="PROGRAMLISTING"
157
WHERE city = name;</PRE
162
> city | temp_lo | temp_hi | prcp | date | name | location
163
---------------+---------+---------+------+------------+---------------+-----------
164
San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
165
San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
171
> Observe two things about the result set:
177
> There is no result row for the city of Hayward. This is
178
because there is no matching entry in the
182
> table for Hayward, so the join
183
ignores the unmatched rows in the <TT
187
shortly how this can be fixed.
192
> There are two columns containing the city name. This is
193
correct because the lists of columns from the
201
> tables are concatenated. In
202
practice this is undesirable, though, so you will probably want
203
to list the output columns explicitly rather than using
209
CLASS="PROGRAMLISTING"
210
>SELECT city, temp_lo, temp_hi, prcp, date, location
212
WHERE city = name;</PRE
224
> Attempt to determine the semantics of this query when the
232
> Since the columns all had different names, the parser
233
automatically found which table they belong to. If there
234
were duplicate column names in the two tables you'd need to
238
> the column names to show which one you
242
CLASS="PROGRAMLISTING"
243
>SELECT weather.city, weather.temp_lo, weather.temp_hi,
244
weather.prcp, weather.date, cities.location
246
WHERE cities.name = weather.city;</PRE
249
It is widely considered good style to qualify all column names
250
in a join query, so that the query won't fail if a duplicate
251
column name is later added to one of the tables.
254
> Join queries of the kind seen thus far can also be written in this
258
CLASS="PROGRAMLISTING"
260
FROM weather INNER JOIN cities ON (weather.city = cities.name);</PRE
263
This syntax is not as commonly used as the one above, but we show
264
it here to help you understand the following topics.
269
Now we will figure out how we can get the Hayward records back in.
270
What we want the query to do is to scan the
274
> table and for each row to find the
278
> row(s). If no matching row is
279
found we want some <SPAN
281
>"empty values"</SPAN
286
> table's columns. This kind
287
of query is called an <I
291
joins we have seen so far are inner joins.) The command looks
295
CLASS="PROGRAMLISTING"
297
FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
299
city | temp_lo | temp_hi | prcp | date | name | location
300
---------------+---------+---------+------+------------+---------------+-----------
301
Hayward | 37 | 54 | | 1994-11-29 | |
302
San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
303
San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
307
This query is called a <I
311
> because the table mentioned on the left of the
312
join operator will have each of its rows in the output at least
313
once, whereas the table on the right will only have those rows
314
output that match some row of the left table. When outputting a
315
left-table row for which there is no right-table match, empty (null)
316
values are substituted for the right-table columns.
323
> There are also right outer joins and full outer joins. Try to
324
find out what those do.
331
We can also join a table against itself. This is called a
335
>. As an example, suppose we wish
336
to find all the weather records that are in the temperature range
337
of other weather records. So we need to compare the
356
> columns of all other
360
> rows. We can do this with the
364
CLASS="PROGRAMLISTING"
365
>SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
366
W2.city, W2.temp_lo AS low, W2.temp_hi AS high
367
FROM weather W1, weather W2
368
WHERE W1.temp_lo < W2.temp_lo
369
AND W1.temp_hi > W2.temp_hi;
371
city | low | high | city | low | high
372
---------------+-----+------+---------------+-----+------
373
San Francisco | 43 | 57 | San Francisco | 46 | 50
374
Hayward | 37 | 54 | San Francisco | 46 | 50
378
Here we have relabeled the weather table as <TT
385
> to be able to distinguish the left and right side
386
of the join. You can also use these kinds of aliases in other
387
queries to save some typing, e.g.:
389
CLASS="PROGRAMLISTING"
391
FROM weather w, cities c
392
WHERE w.city = c.name;</PRE
394
You will encounter this style of abbreviating quite frequently.
402
SUMMARY="Footer navigation table"
413
HREF="tutorial-select.html"
431
HREF="tutorial-agg.html"
441
>Querying a Table</TD
447
HREF="tutorial-sql.html"
455
>Aggregate Functions</TD
b'\\ No newline at end of file'