I'm newish to SQL and playing with a Pokemon database to learn. Starting to grasp some differences with MYSQL, SQLite and PostgreSQL.
SQLlite allows me to use the following query to grab Pokemon with only a single type (they have only one row using the Select statement as type_names.name will generate two rows--one for each type--if they have two types):
-- displays all pokemon of a single type (no dual-types)
SELECT pokemon_species.id,
pokemon_species.identifier,
type_names.name
FROM pokemon_species
JOIN pokemon_types ON pokemon_species.id = pokemon_types.pokemon_id
JOIN type_names ON pokemon_types.type_id = type_names.type_id
GROUP BY 1
HAVING COUNT(*) = 1
ORDER BY pokemon_species.id;
PostgreSQL, however, will give the "[42803] ERROR: column "type_names.name" must appear in the GROUP BY clause or be used in an aggregate function Position: 70" error.
I've found the following query works with PostgreSQL:
-- displays all pokemon of a single type (no dual-types)
WITH species AS (
SELECT pokemon_species.id,
pokemon_species.identifier
FROM pokemon_species
JOIN pokemon_types ON pokemon_species.id = pokemon_types.pokemon_id
JOIN type_names ON pokemon_types.type_id = type_names.type_id
GROUP BY 1, 2
HAVING COUNT(*) = 1
ORDER BY pokemon_species.id
)
SELECT species.*, type_names.name
FROM species
JOIN pokemon_types ON species.id = pokemon_types.pokemon_id
JOIN type_names ON pokemon_types.type_id = type_names.type_id;
Joining the three tables twice, seems redundant and I am wondering--how could this query be written better?
Result example:
id | identifier | type_name
-- | ---------- | ---------
4 | charmander | Fire
5 | charmeleon | Fire
7 | squirtle | Water
8 | wartortle | Water
9 | blastoise | Water
10 | caterpie | Bug
11 | metapod | Bug