在 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.FIRSTThanks @BenLeathers 。 . .嗯,MySQL 没有这样的限制。 嘿 Gordon,感谢您的回复,我认为 MySQL 是我们编写的语言,而不是数据库系统。我正在开发一个 BigQuery 数据库。

以上是关于在 JOIN 的 ON 子句中使用别名的主要内容,如果未能解决你的问题,请参考以下文章

LINQ Join 与 On 子句中的多个条件

如何在 LEFT JOIN ON 子句中使用子选择?

PostgreSQL 中的 SQL JOIN - WHERE 子句中的执行计划与 ON 子句中的不同

CROSS JOIN 是没有 ON 子句的 INNER JOIN 的同义词吗?

如果在 ON 子句中使用 OR,MySQL 将不会在 JOIN 中使用可用索引

JOIN 的 ON 子句中引用的表的顺序是不是重要?