在 JOIN 的 ON 子句中使用别名
Posted
技术标签:
【中文标题】在 JOIN 的 ON 子句中使用别名【英文标题】:Using Aliases in the ON Clause of a JOIN 【发布时间】:2015-02-16 18:15:54 【问题描述】:Stack Overflow 的新手(以及一般的编码)。
我做了一些研究,但无法找到以下问题的答案:
如何将两个表格连接到应用于维度的函数结果,而不是维度本身?
即我想将以下两个表加入函数 lower() 的小写结果,而不是加入大小写不明确的维度。
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
它不允许我加入我在第一个表 (a) 中创建的别名,但是,如果我加入表 a 中的原始维度(first_name 和 last_name),那么结果将基于大小写不明确的维度,并给出不想要的结果。
我希望这很清楚。
感谢您的帮助!
【问题讨论】:
请指出您正在使用的数据库系统并删除不必要的标签。您已标记 BigQuery 和 mysql。谢谢。 糟糕!我没有意识到 MySQL 是一个数据库!我认为那是我们编写的语言。我正在研究 BigQuery 数据库。谢谢! 【参考方案1】:感谢大家的帮助!
尤其是 sprocket,他为我指明了正确的方向!他的代码和我的主要区别在于我的代码没有在第一个 SELECT 子句的每个维度的前面附加表别名(例如 **a.**fistname, **a.**lastname, --- --> 名,姓)
由于表别名,BigQuery 一直给我一个错误。
这是有效的代码。
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
感谢大家的帮助!
【讨论】:
【参考方案2】:尝试使用两个这样的子查询:
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
在您的原始查询中,a 只是 BensData.Donations 的别名,因此您只能加入该表中存在的字段。
【讨论】:
嘿 Sprocket,即使按照您的建议加入两个子查询,我仍然无法加入 ON 别名。我尝试了您的解决方案的更简单版本:SELECT a.firstname FROM (SELECT lower(first_name) as firstname From BensData.Donations) As a JOIN EACH (Select lower(first_name) as first From BensData.Donations) As b ON a.firstname=b.first
它仍然给我以下错误:“Google BigQuery 服务无法编译查询。找不到字段'a_firstname';你的意思是'a.firstname'吗?”我觉得很奇怪,因为“a_firstname”甚至不在代码中谢谢
为了尽可能清楚,我无法加入为维度创建的别名。表别名工作正常。谢谢!【参考方案3】:
我从未听说过join each
,并且它没有被记录为 MySQL 连接的语法(请参阅此处)。
试试这个from
子句:
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
您的版本在列之间的子查询中也缺少逗号。
为清楚起见,您可能应该将from
子句写为:
ON lower(a.firstname) = b.first AND lower(a.lastname) = b.last
或从子查询中删除lower()
。否则,on
子句的实际作用取决于服务器、数据库和表的默认排序规则。
【讨论】:
这是导致我使用“JOIN EACH”cloud.google.com/bigquery/query-reference 的文档,由于某种原因,如果没有“EACH”这个词,它就无法工作在我原来的帖子中,我重新编写了我的代码来尝试找到我问题的核心,但这样做时,我似乎忘记了一些逗号。 这是我最初拥有的代码,它可以工作,但没有正确解决这个问题:SELECT first_name ,last_name ,email ,amount ,total_donated FROM SweetData.Payments 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 SweetData.Payments GROUP BY email2, LAST, FIRST) AS b ON a.email=b.email2 AND a.last_name=b.LAST AND a.first_name=b.FIRST
不幸的是,BigQuery 似乎不喜欢将 ON CLAUSE 中的维度包装在 lower() 函数中。当我用以下内容替换 ON 子句时,出现错误:ON lower(a.email)=b.email2 AND lower(a.last_name)=b.LAST AND lower(a.first_name)=b.FIRST
Thanks
@BenLeathers 。 . .嗯,MySQL 没有这样的限制。
嘿 Gordon,感谢您的回复,我认为 MySQL 是我们编写的语言,而不是数据库系统。我正在开发一个 BigQuery 数据库。以上是关于在 JOIN 的 ON 子句中使用别名的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL 中的 SQL JOIN - WHERE 子句中的执行计划与 ON 子句中的不同
CROSS JOIN 是没有 ON 子句的 INNER JOIN 的同义词吗?