Open haydnba opened 6 years ago
Wow thanks so much for this - was just trying to figure my head around why you need linking tables (rather than just using JOIN
and this clears it up nicely π
Have some complimentary emojis: πΎπ¦π
Thanks for such lovely emojis!!!
Concatenate String Values with Aggregate Functions in PostgreSQL
The problem:
The proper way to handle a many-to-many relationship in a relational database management system is a pair of separate Primary-Keyed tables linked by a third mediating table associating their keys as Foreign-Keys e.g.
Pizzas to Toppings - one pizza may have many toppings, and one topping may be on many pizzas, so:
If we want to pull all the pizzas with their toppings from the database we will need to use the linking table to associate each pizza record to its toppings.
Using a
JOIN
in our query we will expect the cartesian product of the two Primary-Keyed tables ('pizza' and 'topping') as expressed by the linking table 'pizza_topping' - something like:and so on...
The result above would be produced by the following query:
But this means that you are duplicating your records. If you don't want a new results row for every unique combination of pizza and topping, but just for every unique pizza BUT you still want to list every topping specific to each pizza record, you need to use an aggregate function within a subquery as follows:
The above query should return something like the following:
The critical elements of the query are
array_agg()
(it could bestring_agg
instead - you would need to supply a delimiter) within the subqueryWHERE
clause which associates the subquery aggregation to each current pizza Primary Key - if this clause were omitted then the subquery would return an array of every topping record for each pizza and not just those associated to the given pizzaSee this, and this on StackOverflow for more examples.
Play around with this SQL Fiddle.