Skip to content

Commit 651030a

Browse files
committed
doc, intagg: fix one-to-many mention to many-to-many
Reported-by: Christophe Courtois Discussion: https://postgr.es/m/aa7cfd73-0d8d-596a-b684-39faa479afa5@dalibo.com Author: Christophe Courtois Backpatch-through: master
1 parent 719b342 commit 651030a

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

doc/src/sgml/intagg.sgml

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,22 @@
5454
<title>Sample Uses</title>
5555

5656
<para>
57-
Many database systems have the notion of a one to many table. Such a table
57+
Many database systems have the notion of a many to many table. Such a table
5858
usually sits between two indexed tables, for example:
5959

6060
<programlisting>
61-
CREATE TABLE left (id INT PRIMARY KEY, ...);
62-
CREATE TABLE right (id INT PRIMARY KEY, ...);
63-
CREATE TABLE one_to_many(left INT REFERENCES left, right INT REFERENCES right);
61+
CREATE TABLE left_table (id INT PRIMARY KEY, ...);
62+
CREATE TABLE right_table (id INT PRIMARY KEY, ...);
63+
CREATE TABLE many_to_many(id_left INT REFERENCES left_table,
64+
id_right INT REFERENCES right_table);
6465
</programlisting>
6566

6667
It is typically used like this:
6768

6869
<programlisting>
69-
SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
70-
WHERE one_to_many.left = <replaceable>item</replaceable>;
70+
SELECT right_table.*
71+
FROM right_table JOIN many_to_many ON (right_table.id = many_to_many.id_right)
72+
WHERE many_to_many.id_left = <replaceable>item</replaceable>;
7173
</programlisting>
7274

7375
This will return all the items in the right hand table for an entry
@@ -76,7 +78,7 @@ SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
7678

7779
<para>
7880
Now, this methodology can be cumbersome with a very large number of
79-
entries in the <structname>one_to_many</structname> table. Often,
81+
entries in the <structname>many_to_many</structname> table. Often,
8082
a join like this would result in an index scan
8183
and a fetch for each right hand entry in the table for a particular
8284
left hand entry. If you have a very dynamic system, there is not much you
@@ -85,43 +87,45 @@ SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
8587

8688
<programlisting>
8789
CREATE TABLE summary AS
88-
SELECT left, int_array_aggregate(right) AS right
89-
FROM one_to_many
90-
GROUP BY left;
90+
SELECT id_left, int_array_aggregate(id_right) AS rights
91+
FROM many_to_many
92+
GROUP BY id_left;
9193
</programlisting>
9294

9395
This will create a table with one row per left item, and an array
9496
of right items. Now this is pretty useless without some way of using
9597
the array; that's why there is an array enumerator. You can do
9698

9799
<programlisting>
98-
SELECT left, int_array_enum(right) FROM summary WHERE left = <replaceable>item</replaceable>;
100+
SELECT id_left, int_array_enum(rights) FROM summary WHERE id_left = <replaceable>item</replaceable>;
99101
</programlisting>
100102

101103
The above query using <function>int_array_enum</function> produces the same results
102104
as
103105

104106
<programlisting>
105-
SELECT left, right FROM one_to_many WHERE left = <replaceable>item</replaceable>;
107+
SELECT id_left, id_right FROM many_to_many WHERE id_left = <replaceable>item</replaceable>;
106108
</programlisting>
107109

108110
The difference is that the query against the summary table has to get
109111
only one row from the table, whereas the direct query against
110-
<structname>one_to_many</structname> must index scan and fetch a row for each entry.
112+
<structname>many_to_many</structname> must index scan and fetch a row for each entry.
111113
</para>
112114

113115
<para>
114116
On one system, an <command>EXPLAIN</command> showed a query with a cost of 8488 was
115117
reduced to a cost of 329. The original query was a join involving the
116-
<structname>one_to_many</structname> table, which was replaced by:
118+
<structname>many_to_many</structname> table, which was replaced by:
117119

118120
<programlisting>
119-
SELECT right, count(right) FROM
120-
( SELECT left, int_array_enum(right) AS right
121-
FROM summary JOIN (SELECT left FROM left_table WHERE left = <replaceable>item</replaceable>) AS lefts
122-
ON (summary.left = lefts.left)
121+
SELECT id_right, count(id_right) FROM
122+
( SELECT id_left, int_array_enum(rights) AS id_right
123+
FROM summary
124+
JOIN (SELECT id FROM left_table
125+
WHERE id = <replaceable>item</replaceable>) AS lefts
126+
ON (summary.id_left = lefts.id)
123127
) AS list
124-
GROUP BY right
128+
GROUP BY id_right
125129
ORDER BY count DESC;
126130
</programlisting>
127131
</para>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy