简体   繁体   中英

Using Aliases in the ON Clause of a JOIN

New to Stack Overflow (and coding in general).

I did some research but was unable to find an answer to the following problem:

How can I join two tables ON the results of functions applied to dimensions, rather than on the dimensions themselves?

ie I want to join the following two tables on the lowercase results of the function lower() rather than joining on the case ambiguous dimensions as they are.

SELECT
lower(first_name) as firstname
,lower(last_name) as lastname
,lower(email) as email1
,total_donated
From BensData.Donations As a

JOIN EACH

(Select
lower(first_name) as first
,lower(last_name) as last
,lower(email) as email2
,sum(amount) as total_donated
From BensData.Donations 
GROUP BY email2, first, last) As b

ON a.email1=b.email2 AND a.firstname=b.first AND a.lastname=b.last

It does not let me join on the aliases I create in the first table (a), however, if I join ON the original dimensions in table a (first_name and last_name) then the results are based on the case ambiguous dimensions, and give an undesired result.

I hope that was clear.

Thanks for any help!

Try using two subqueries like this:

SELECT
a.firstname
,a.lastname
,a.email1
,a.total_donated
FROM

(SELECT
lower(first_name) as firstname
,lower(last_name) as lastname
,lower(email) as email1
,total_donated
From BensData.Donations) As a

JOIN EACH

(Select
lower(first_name) as first
,lower(last_name) as last
,lower(email) as email2
,sum(amount) as total_donated
From BensData.Donations 
GROUP BY email2, first, last) As b

ON a.email1=b.email2 AND a.firstname=b.first AND a.lastname=b.last

In your original query, a is just an alias for BensData.Donations, so you can only join on fields present in that table.

I have never heard of join each and it is not documented as a syntax for MySQL joins (see here).

Try this from clause:

From BensData.Donations a JOIN
     (Select lower(first_name) as first, lower(last_name) as last,
             sum(amount) as total_donated
      From BensData.Donations 
      GROUP BY first, last
     ) b
     ON a.firstname = b.first AND a.lastname = b.last

Your version was also missing commas in the subquery between the columns.

For clarity, you should probably write the from clause as:

     ON lower(a.firstname) = b.first AND lower(a.lastname) = b.last

or remove the lower() from the subquery. Otherwise, you are dependent on the default collations for the server, database, and table for what the on clause really does.

Thanks for everyone's help!

Particularly sprocket who pointed me in the right direction! The main difference in his code and mine is that mine does not have the table aliases appended on the front of each dimension of the first SELECT clause (eg **a.**fistname, **a.**lastname, -----> firstname, lastname)

For some reason BigQuery kept giving me an error because of the table aliases.

Here's the code that worked.

SELECT
firstname
,lastname
,email1
,total_donated
FROM

(SELECT
lower(first_name) as firstname
,lower(last_name) as lastname
,lower(email) as email1
From BensData.Donations) As a

JOIN EACH

(Select
lower(first_name) as first
,lower(last_name) as last
,lower(email) as email2
,sum(float(amount)) as total_donated
From BensData.Donations 
GROUP BY email2, first, last) As b

ON a.email1=b.email2 AND a.firstname=b.first AND a.lastname=b.last

Thanks all for your help!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM