PostgreSQL Syntax Error near JOIN, or anyother

483 Views Asked by At

I have this Olympics Dataset which i imported on PostgreSQL database. I want to Create table using select statement and somemore is there. But I'm getting this error:

ERROR: column foo.age does not exist LINE 17: (case when foo.Age=NULL then foo.Age=26 else foo.Age end... ^ HINT: Perhaps you meant to reference the column "ae.age". SQL state: 42703 Character: 628

what I indent to do is:

  1. change the type of column age,height,weight
  2. Take the above data and join it with another query where I want to replace NULL value
  3. create new table using above two data. all this in one go. I still new to this database, I actually did it in SQLite and it worked fine but here it wont work . If you have any other way to do this please tell me. Thank You! Here is my code :
CREATE TABLE Female_participants AS 
SELECT DISTINCT
   ae.id AS Player_id,
   ae.Name,
   ( /* Here what i want to do is im thinking like foo table which i joined to this table is giving me 
       (this and following column where i want to replace NULL values) age,weight and height as int,float,float */
      CASE
         WHEN/*foo.age suppose to be column from foo table which is casted to int*/
            foo.Age = NULL 
         THEN
            foo.Age = 26 
         ELSE
            foo.Age 
      END
   )
   AS Age , 
   (
      CASE
         WHEN/*foo.height suppose to be float*/
            foo.height = NULL 
         THEN
            FLOOR(AVG(foo.height)) 
         ELSE
            foo.height 
      END
   )
   AS Height, 
   (
      CASE
         WHEN /*foo.Weight suppose to be float*/
            foo.weight = NULL 
         THEN
            FLOOR(AVG(foo.weight)) 
         ELSE
            foo.weight 
      END
   )
   AS weight, City, Team AS Country 
FROM
   athlete_events ae 
   INNER JOIN
      (
         SELECT DISTINCT
            id,
            /*Here i want to convert the dtype from TEXT to int or float*/
            CAST(age AS INT) thag,
            CAST(height AS FLOAT) AS thht,
            CAST(weight AS FLOAT) AS thwt 
         FROM
            athlete_events /* i read on https://www.postgresqltutorial.com/.. that i can self-join table */
      )
      AS foo /*Joining this table on id*/
      ON foo.id = ae.id 
GROUP BY
   id,
   name
3

There are 3 best solutions below

5
On BEST ANSWER

More or less your query can be boil down to this :

SELECT DISTINCT
   ae.id AS Player_id,
   ae.Name,
   coalesce( foo.age::int ,26 ) ::int  AS Age , 
   coalesce( foo.height::float , FLOOR(AVG(foo.height::float ) over())::float ) ::float  AS Height , 
   coalesce( foo.weight::float , FLOOR(AVG(foo.weight::float ) over())::float ) ::float  AS Weight , 
   City,
   Team AS Country 
FROM
   athlete_events foo ;

try reading the following links for coalesce , double colon cast , and aggregate function without group by clause .

0
On

there are two problems in your code:

  1. relation "foo" does not really have column "age", it's columns are id,thag,thht,thwt
  2. operator "smth = NULL" does not exist, must use smth IS NULL or use COALESCE function for simple cases like here the code can be like this:
    CREATE TABLE Female_participants AS 
    SELECT DISTINCT
       ae.id AS Player_id, 
       ae.Name, 
       COALESCE(foo.Age, 26) AS Age , 
       COALESCE(foo.height, foo_avg.height) AS Height, 
       COALESCE(foo.weight, foo_avg.weight) AS weight, 
       City, 
       Team AS Country 
    FROM athlete_events AS ae 
    INNER JOIN (
        SELECT DISTINCT
           id,
           age::INT,
           height::FLOAT,
           weight::FLOAT 
        FROM athlete_events
    ) AS foo ON foo.id = ae.id 
    INNER JOIN (
        SELECT
           AVG(height::FLOAT) AS height,
           AVG(weight::FLOAT) AS weight
        FROM athlete_events
    ) AS foo_avg ON TRUE;
1
On

The problem depends on the fact that when subquerying athlete_avents you rename the columns age, height and weight as thag, thht, thwt .

So in your CASE blocks you should use the renamed column names and not the original ones.

I.E.

   ( /* Here what i want to do is im thinking like foo table which i joined to this table is giving me 
       (this and following column where i want to replace NULL values) age,weight and height as int,float,float */
      CASE
         WHEN/*foo.age suppose to be column from foo table which is casted to int*/
            foo.thag= NULL 
         THEN
            foo.thag = 26 
         ELSE
            foo.thag
      END
   )
   AS Age , 
   (
      CASE
         WHEN/*foo.height suppose to be float*/
            foo.thht= NULL 
         THEN
            FLOOR(AVG(foo.thht)) 
         ELSE
            foo.thht
      END
   )
   AS Height, 
   (
      CASE
         WHEN /*foo.Weight suppose to be float*/
            foo.thwt = NULL 
         THEN
            FLOOR(AVG(foo.thwt )) 
         ELSE
            foo.thwt 
      END
   )
   AS weight