0

In the query below, I would like to create two new variables: one variable derived from postcode, another derived from area (which is derived from postcode).

 select postcode, 
    case when substring(postcode for 2) = 'YO' then 'York',
         when substring(postcode for 1) = 'E' then 'London E'
    ... 
    else 'unknown'
    end as area,
    case when area in ('York', 'London E') then 'England'
         when area = 'Belfast' then 'Northern Ireland'
    else 'unknown'
    end as country
   from countries 
   group by area, country

Initial output:

postcode
SE14 5XG
EX1 3AL
E2 0QP
NW7 2NT
Gu2 8nj

Expected output:

 postcode   area      country
 SE14 5XG   London SE England
 EX1 3AL    Exeter   England
 ...
 NW7 2NT    London NW England
 Gu2 8nj    Guildford England

The code above returns "error: column "area" does not exist"

in PostGreSQL.

2 Answers 2

1

You can't use alias of one column in the other one.

The first thing you could do is to use the same condition for country

...
case when substring(postcode for 2) = 'YO' or substring(postcode for 1) = 'E' 
     then 'England'
     when substring(postcode for 2) ...
else 'unknown'
...

If you really care about the names, you could use a nested query

select postcode, area,
    case when area in ('York', 'London E') then 'England'
         when area = 'Belfast' then 'Northern Ireland'
    else 'unknown'
    end as country
from (
 select postcode, 
    case when substring(postcode for 2) = 'YO' then 'York',
         when substring(postcode for 1) = 'E' then 'London E'
    ... 
    else 'unknown'
    end as area
   from countries 
   group by area
)
group by country;
Sign up to request clarification or add additional context in comments.

Comments

0

You can use a lateral join to define area:

select c.postcode, v.area,
       (case when v.area in ('York', 'London E') then 'England'
              when v.area = 'Belfast' then 'Northern Ireland'
              else 'unknown'
        end) as country
from countries c cross join lateral
     (values (case when substring(c.postcode for 2) = 'YO' then 'York'
                   when substring(c.postcode for 1) = 'E' then 'London E'
                   ... 
                   else 'unknown'
              end)
     ) v(area);

Note that this fixes some syntax errors and removes the group by (which doesn't make sense in your query).

You might find it simpler to use a lookup:

select c.postcode,
       coalesce(v.area, 'unknown') as area,
       coalesce(v.country, 'unknown') as country
from countries c left join
     (values ('YO%', 'York', 'England'),
             ('E%', 'London E', 'England'),
             . . .
     ) v(pattern, area, country)
     on c.postcode like v.pattern;

   

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.