Join with table alias

This commit is contained in:
Billy Chan 2021-10-13 20:56:05 +08:00 committed by Chris Tsang
parent 864ec522b8
commit 01eff84ce8
3 changed files with 53 additions and 17 deletions

View File

@ -31,7 +31,7 @@ impl<E> Select<E>
where
E: EntityTrait,
{
fn apply_alias(mut self, pre: &str) -> Self {
pub(crate) fn apply_alias(mut self, pre: &str) -> Self {
self.query().exprs_mut_for_each(|sel| {
match &sel.alias {
Some(alias) => {
@ -77,11 +77,14 @@ where
F: EntityTrait,
{
pub(crate) fn new(query: SelectStatement) -> Self {
Self::new_without_prepare(query).prepare_select()
}
pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {
Self {
query,
entity: PhantomData,
}
.prepare_select()
}
fn prepare_select(mut self) -> Self {

View File

@ -1,5 +1,9 @@
use crate::{EntityTrait, Linked, QuerySelect, Related, Select, SelectTwo, SelectTwoMany};
use crate::{
join_tbl_on_condition, unpack_table_ref, EntityTrait, IdenStatic, Iterable, Linked,
QuerySelect, Related, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,
};
pub use sea_query::JoinType;
use sea_query::{Alias, Expr, IntoIden, SeaRc, SelectExpr};
impl<E> Select<E>
where
@ -65,10 +69,35 @@ where
T: EntityTrait,
{
let mut slf = self;
for rel in l.link() {
slf = slf.join(JoinType::LeftJoin, rel);
for (i, rel) in l.link().into_iter().enumerate() {
let to_tbl = Alias::new(&format!("r{}", i)).into_iden();
let from_tbl = if i > 0 {
Alias::new(&format!("r{}", i - 1)).into_iden()
} else {
unpack_table_ref(&rel.from_tbl)
};
slf.query().join_as(
JoinType::LeftJoin,
unpack_table_ref(&rel.to_tbl),
SeaRc::clone(&to_tbl),
join_tbl_on_condition(from_tbl, to_tbl, rel.from_col, rel.to_col),
);
}
slf.select_also(T::default())
slf = slf.apply_alias(SelectA.as_str());
let mut select_two = SelectTwo::new_without_prepare(slf.query);
for col in <T::Column as Iterable>::iter() {
let alias = format!("{}{}", SelectB.as_str(), col.as_str());
select_two.query().expr(SelectExpr {
expr: Expr::tbl(
Alias::new(&format!("r{}", l.link().len() - 1)).into_iden(),
col.into_iden(),
)
.into(),
alias: Some(SeaRc::new(Alias::new(&alias))),
});
}
select_two
}
}
@ -291,10 +320,10 @@ mod tests {
.to_string(),
[
r#"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,"#,
r#"`filling`.`id` AS `B_id`, `filling`.`name` AS `B_name`, `filling`.`vendor_id` AS `B_vendor_id`"#,
r#"`r1`.`id` AS `B_id`, `r1`.`name` AS `B_name`, `r1`.`vendor_id` AS `B_vendor_id`"#,
r#"FROM `cake`"#,
r#"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id`"#,
r#"LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id`"#,
r#"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id`"#,
r#"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`"#,
]
.join(" ")
);
@ -309,11 +338,11 @@ mod tests {
.to_string(),
[
r#"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,"#,
r#"`vendor`.`id` AS `B_id`, `vendor`.`name` AS `B_name`"#,
r#"`r2`.`id` AS `B_id`, `r2`.`name` AS `B_name`"#,
r#"FROM `cake`"#,
r#"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id`"#,
r#"LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id`"#,
r#"LEFT JOIN `vendor` ON `filling`.`vendor_id` = `vendor`.`id`"#,
r#"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id`"#,
r#"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`"#,
r#"LEFT JOIN `vendor` AS `r2` ON `r1`.`vendor_id` = `r2`.`id`"#,
]
.join(" ")
);

View File

@ -490,6 +490,7 @@ pub async fn having() {
pub async fn linked() -> Result<(), DbErr> {
use common::bakery_chain::Order;
use sea_orm::{SelectA, SelectB};
use sea_query::{Alias, Expr};
let ctx = TestContext::new("test_linked").await;
create_tables(&ctx.db).await?;
@ -673,13 +674,16 @@ pub async fn linked() -> Result<(), DbErr> {
.find_also_linked(baker::BakedForCustomer)
.select_only()
.column_as(baker::Column::Name, (SelectA, baker::Column::Name))
.column_as(customer::Column::Name, (SelectB, customer::Column::Name))
.column_as(
Expr::tbl(Alias::new("r4"), customer::Column::Name).into_simple_expr(),
(SelectB, customer::Column::Name),
)
.group_by(baker::Column::Id)
.group_by(customer::Column::Id)
.group_by(Expr::tbl(Alias::new("r4"), customer::Column::Id).into_simple_expr())
.group_by(baker::Column::Name)
.group_by(customer::Column::Name)
.group_by(Expr::tbl(Alias::new("r4"), customer::Column::Name).into_simple_expr())
.order_by_asc(baker::Column::Id)
.order_by_asc(customer::Column::Id)
.order_by_asc(Expr::tbl(Alias::new("r4"), customer::Column::Id).into_simple_expr())
.into_model()
.all(&ctx.db)
.await?;