Hive: SemanticException [Error 10002]: Line 3:21 Invalid column reference 'name'

41,374

Solution 1

If you group by a column, your select statement can only select a) that column, b) columns derived only from that column, or c) a UDAF applied to other columns.

In this case, you're only grouping by list.id, so when you try to select list.name, that's invalid. Think about it this way: what if your list table contained the following two entries:

id|name |genre
--+-----+------
01|name1|comedy
01|name2|horror

What would you expect this query to return:

select list.id, list.name, list.genre from list group by list.id;

In this case it's nonsensical. I'm guessing that id in reality is a primary key, but note that hive does not know this, so the above data set is perfectly valid.

With all that in mind, it's not clear to me how to fix it because I don't know the desired output. For example, let's say without the group by (just the join), you have as output:

id|name |genre |rating
--+-----+------+-------
01|name1|comedy|'pretty good'
01|name1|comedy|'bad'
02|name2|horror|'9/10'
03|name3|action|NULL

What would you want the output to be with the group by? What are you trying to accomplish by doing the group by?

Solution 2

OK let me see if I can ask this in a better way.

Here are my two tables

Movies list table - Consists of movies information

ID | Movie Name | Genre
1  | Movie 1    | comedy
2  | movie 2    | action
3  | movie 3    | thriller

And I have ratings table

MOVIE_ID | USER ID | RATING on 5 | TIMESTAMP
1        |  xyz    | 5           | 12345612
1        |  abc    | 4           | 23232312
2        |  zvc    | 1           | 12321123
2        |  zyx    | 2           | 12312312

What I would like to do is get the output in the following way:

Movie ID | Movie Name | Genre    | Rating Average
1        | Movie 1    | comedy   | 4.5 
2        | Movie 2    | action   | 1.5

I am not a db expert but I understand this, when you group the data together you need to convert the multiple values to the scalar values or all the values, if string should be same right?

For example in my previous case, I was grouping them together as a string. So which is okay for list.id, list.name and list.genre, but the list.rating, well that is always going to give some problem here (I just learnt PIG along with hive, so grouping works differently there)

So to tackle the problem, I casted the rating and averaged it out and stored it in the float table. Have a look at my code below:

CREATE TABLE movies.movierating(id STRING, name STRING, genre STRING, rating FLOAT);

INSERT OVERWRITE TABLE movies.movierating
SELECT list.id, list.name, list.genre, AVG(cast(rating.rating as FLOAT)) from movies.list list LEFT JOIN movies.rating rating ON (list.id=rating.id) GROUP BY list.id, list.name,list.genre order by list.id DESC;

Thank you for your explanation. I might save the following question for the next thread but here is my observation:

The performance of the Overall job is reduced when performing Grouping and Joining together than to do it in two separate queries. For the same job, I had changed the code a bit to perform the grouping first and then joining the data and the over all time was reduced by 40 seconds. Earlier it was taking 140 seconds and now it is taking 100 seconds. Any reasons to that?

Once again thank you for your explanation.

Solution 3

I came across same issue:

org.apache.hadoop.hive.ql.parse.SemanticException: Invalid column reference "charge_province"

After I put the "charge_province" in the group by, the issue is gone. I don't know why.

Share:
41,374
Piyush Chitkara
Author by

Piyush Chitkara

Updated on April 23, 2020

Comments

  • Piyush Chitkara
    Piyush Chitkara about 4 years

    I am using the following hive query script for the version 0.13.0

    DROP TABLE IF EXISTS movies.movierating;
    DROP TABLE IF EXISTS movies.list;
    DROP TABLE IF EXISTS movies.rating;
    DROP DATABASE IF EXISTS movies;
    
    ADD JAR /usr/local/hadoop/hive/hive/lib/RegexLoader.jar;
    
    CREATE DATABASE IF NOT EXISTS movies;
    
    CREATE EXTERNAL TABLE IF NOT EXISTS movies.list (id STRING, name STRING, genre STRING)
    ROW FORMAT SERDE 'com.cisco.hadoop.loaders.RegexSerDe'with SERDEPROPERTIES(
     "input.regex"="^(.*)\\:\\:(.*)\\:\\:(.*)$",
     "output.format.string"="%1$s %2$s %3$s");
    
     CREATE EXTERNAL TABLE IF NOT EXISTS movies.rating (id STRING, userid STRING, rating STRING, timestamp STRING)
     ROW FORMAT SERDE 'com.cisco.hadoop.loaders.RegexSerDe'
     with SERDEPROPERTIES(
     "input.regex"="^(.*)\\:\\:(.*)\\:\\:(.*)\\:\\:(.*)$",
     "output.format.string"="%1$s %2$s %3$s %4$s");
    
     LOAD DATA LOCAL INPATH 'ml-10M100K/movies.dat' into TABLE movies.list;
     LOAD DATA LOCAL INPATH 'ml-10M100K/ratings.dat' into TABLE movies.rating;
    
     CREATE TABLE movies.movierating(id STRING, name STRING, genre STRING, rating STRING);
    
     INSERT OVERWRITE TABLE movies.movierating
     SELECT list.id, list.name, list.genre, rating.rating from movies.list list LEFT JOIN movies.rating rating ON (list.id=rating.id) GROUP BY list.id;
    

    The issue is when I execute the script without the "GROUP BY" clause it works fine. But when I execute it with the "GROUP BY" clause, I get the following error

    FAILED: SemanticException [Error 10002]: Line 4:21 Invalid column reference 'name'
    

    Any ideas what is happening here?

    Appreciate your help

    Thanks!