I want to return all cities whose all postal codes are contained in an array of certain postal codes.
On the backend I have an array containing postal codes. The array looks as follows:
[41200, 41201, 41202, 42500, 42501, 42504, 42505, 42506].
Using sql query, I retrieve all available cities from the database along with all postal codes assigned to them. Example:
City | Postcodes |
---|---|
New York | 10001, 10002, 10003, 10004, … |
I want to add a certain condition to this query that will make the query return all cities whose all postal codes are included in this array.
Easy example:
Table: [1, 2, 3, 4, 5, 6]
SQL query result:
City | Postcodes |
---|---|
City 1 | 1, 2, 7 |
City 2 | 1, 4 |
City 3 | 1, 2, 3, 4, 5, 6 |
City 4 | 1, 3, 2, 8 |
After adding the condition, the query should return city 2 and city 3 BECAUSE table includes all of city 2 / city 3 postcodes but it does not include all the postcodes from city 1 and 4. Thank you.
That’s my query:
SELECT gmina, kody
FROM (
SELECT gmina, STRING_AGG(DISTINCT kod, ', ') AS kody
FROM ser_strumieniowanie_kody ser
LEFT JOIN hog_miasta hog ON ser.st_kod = hog.kod
WHERE ser.pm = ser.av
GROUP BY gmina
) AS subquery where ...
2
Answers
That needs a lot of conversions to have on bioth side arays
athen you can use <@ as array operator see
https://www.postgresql.org/docs/current/functions-array.html
fiddle
Based on the query you added, I’m assuming you are dealing with a normalised structure and you only presented the values in an aggregated form to illustrate their intermediate state in your array-oriented approach.
If I’m guessing your columns right, you can swap out
string_agg()
for anarray_agg()
to get access to array containment operator@>
and its commutator<@
and specify your condition in theHAVING
clause. Demo at db<>fiddle:In a
left join
, rows in the left table without a match in the right table get anull
in all right table’s columns. You could use that to only keep those cities where every code had a match:That’s demonstrably faster, especially when supported by covering indexes:
At the end of the demo, there’s a test on 200k records from 10k cities with up to 40 out of 300 codes.