具有别名的同一列上的多个连接
Posted
技术标签:
【中文标题】具有别名的同一列上的多个连接【英文标题】:multiple joins on the same column with alias 【发布时间】:2020-04-21 09:44:02 【问题描述】:我正在尝试将多个表连接在一起。需要在同一列上连接 2 个表。但是,我需要使用指定的列别名,因为这些值仅在替换文本后才会匹配。 所以我有;
table1:
| date_time | product_quote | category_id
table2:
| product_id | category_id
table3:
| date | product_id | sales
table4:
| category_id | category_name
“product_quote”的值是一个包含 product_id 的字符串。我可以通过使用 REPLACE 来解决这个问题。
想要的结果:
| year | month | week | day | product_id | quotes | sales | category_name
我正在尝试使用以下查询,但它抱怨“product_id”不明确。 当我在 table2.product_id 上进行第三次连接时,它会执行查询,但我得到了错误的销售数字。 也不确定如何(重新)在 join 语句中使用日期别名(年、月等)。
SELECT
date_part('year', table1.date_time) as "year",
date_part('month', table1.date_time) as "month",
date_part('week', table1.date_time) as "week",
date_part('day', table1.date_time) as "day",
REPLACE(REPLACE(table1.product_quote,'/quotes/',''),'.pdf','') as "product_id",
count(table1.product_quote) as quotes,
table3.sales,
table4.category_name
from table1
left join table2 ON "product_id" = table2.product_id
left join table4 ON table2.category_id = table4.category_id
left join table3 ON "product_id" = table3.product_id AND
date_part('year', table3.date) = date_part('year', table1.date_time) AND
date_part('month', table3.date) = date_part('month', table1.date_time) AND
date_part('day', table3.date) = date_part('day', table1.date_time)
where date_part('year', table1.date_time) = '2020'
group by year, month, week, day, table2.product_id, table1.product_quote, table4.category_name, table3.sales
这是我应该作为 1 个带有 3 个连接的查询执行的操作,还是我需要使用子查询? (如果是的话,怎么做?)
【问题讨论】:
【参考方案1】:我认为您假设您是根据SELECT
部分中的“product_id”投影(或您称之为“别名”)加入的。但事实并非如此。在 SQL 中,JOIN
总是首先出现,所以JOIN
部分并不“知道”SELECT
-部分。
要解决你的问题,你需要
在JOIN
中使用REPLACE
表达式两次
始终在表前加上 product_id
SELECT
date_part('year', table1.date_time) as "year",
date_part('month', table1.date_time) as "month",
date_part('week', table1.date_time) as "week",
date_part('day', table1.date_time) as "day",
REPLACE(REPLACE(table1.product_quote,'/quotes/',''),'.pdf','') as "product_id",
count(table1.product_quote) as quotes,
table3.sales,
table4.category_name
from table1
left join table2 ON REPLACE(REPLACE(table1.product_quote,'/quotes/',''),'.pdf','') = table2.product_id
left join table4 ON table2.category_id = table4.category_id
left join table3 ON REPLACE(REPLACE(table1.product_quote,'/quotes/',''),'.pdf','') = table3.product_id AND
date_part('year', table3.date) = date_part('year', table1.date_time) AND
date_part('month', table3.date) = date_part('month', table1.date_time) AND
date_part('day', table3.date) = date_part('day', table1.date_time)
where date_part('year', table1.date_time) = '2020'
group by year, month, week, day, table2.product_id, table1.product_quote, table4.category_name, table3.sales
至少以上是基本解决方案。
如果您使用子选择在join
之前投影table1
,您也可以使用别名:
SELECT
t1.year,
t1.month,
t1.week,
t1.day,
t1.product_id,
t1.quotes,
table3.sales,
table4.category_name
FROM
(
SELECT
date_part('year', table1.date_time) as "year",
date_part('month', table1.date_time) as "month",
date_part('week', table1.date_time) as "week",
date_part('day', table1.date_time) as "day",
REPLACE(REPLACE(table1.product_quote,'/quotes/',''),'.pdf','') as "product_id",
count(table1.product_quote) as quotes,
from table1
) as t1
left join table2 ON t1.product_id = table2.product_id
left join table4 ON table2.category_id = table4.category_id
left join table3 ON t1.product_id = table3.product_id AND
date_part('year', table3.date) = t1.year AND
date_part('month', table3.date) = t1.month AND
date_part('day', table3.date) = t1.day
where t1.year = '2020'
group by t1.year, t1.month, t1.week, t1.day, table2.product_id, t1.product_quote, table4.category_name, table3.sales
【讨论】:
谢谢!我没有意识到连接是首先执行的(这应该很明显;)以上是关于具有别名的同一列上的多个连接的主要内容,如果未能解决你的问题,请参考以下文章