question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Trouble using subquery in left joins without using getRawMany

See original GitHub issue

Issue type:

[X] question [ ] bug report [ ] feature request [ ] documentation issue

Database system/driver:

[ ] cordova [ ] mongodb [ ] mssql [ ] mysql / mariadb [ ] oracle [X] postgres [ ] cockroachdb [ ] sqlite [ ] sqljs [ ] react-native [ ] expo

TypeORM version:

[ ] latest [ ] @next [X] 0.2.16 (or put your version here)

Steps to reproduce or a small repository showing the problem: I’m trying to add pagination to left joins using subqueries but I can’t figure it out how to do it properly, or if it can be done at all.

    qb.leftJoinAndSelect(
      subq =>
        subq
          .select()
          .from(Centres, 'centres')
          .take(1),
      'centres',
      'centres.deleted = :deleted',
      { deleted: false },
    );
    return await qb.getMany();

This is my code so far and with that I do not get the relation injected into my user object. It works fine if I execute the query with getRawMany() but it won’t work with the format i’m trying to get.

Any ideas how to solve this or with any other way to paginate the relations in my queries?

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:2
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

10reactions
Khanjicommented, Jul 8, 2019

Got the same issue when using a subquery, or a select statement.

So it seems when you do a subquery or a select stament like so:

this.financeRepository.createQueryBuilder('finance')
      .select(`
          SUM(finance.revenue) as finance_revenue, 
          SUM(finance.first_interview) as finance_first_interview, 
          SUM(finance.second_interview) as finance_second_interview, 
          SUM(finance.offer) as finance_offer,
          SUM(finance.deal) as finance_deal,
          finance.employee_id as finance_employee_id
          `)
      .leftJoinAndSelect('finance.employee', 'employee')
      .groupBy('finance.employee_id')
      .getRawAndEntities();

The Raw data is correct:

{
    "raw": [
        {
            "employee_id": 1,
            "employee_name": "John",
            "employee_surname": "Doe",
            "employee_date_of_birth": "1989-07-04T00:00:00.000Z",
            "employee_avatar": "picture",
            "employee_tune": "tune",
            "employee_inactive": 0,
            "finance_revenue": "10400",
            "finance_first_interview": "1",
            "finance_second_interview": "2",
            "finance_offer": "0",
            "finance_deal": "3",
            "finance_employee_id": 1
        }
    ],
    "entities": []
}

But as you can see, the entity is empty. It does not matter how i format or name the selectable columns or how i format or name the entity properties. It does not map to an entity when you use a subquery or a select statement.

This is how the entities look like at my end:

  • Employee entity
@Entity()
export default class Employee {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({type: "varchar"})
  name: string;

  @Column({type: "varchar"})
  surname: string;

  @Column({type: "datetime"})
  date_of_birth: string;

  @Column({type: "text"})
  avatar: string;

  @Column({type: "text"})
  tune: string;

  @Column({type: "boolean", default: false})
  inactive: boolean;

  @OneToMany(type => Finance, finance => finance.employee, {eager: true})
  finances: Finance[];

  @ManyToMany(type => Team, {eager: true})
  @JoinTable()
  teams: Team[];

  @ManyToMany(type => Achievement, {eager: true})
  @JoinTable()
  achievements: Achievement[];

  test: Finance;
}
  • Finance entity
@Entity()
export default class Finance {
  @PrimaryGeneratedColumn()
  id: number;

  @ManyToOne(type => Employee)
  @JoinColumn({ referencedColumnName: "id", name: "employee_id" })
  employee:Employee;

  @Column({type: "int"})
  first_interview: number;

  @Column({type: "int"})
  second_interview: number;

  @Column({type: "int"})
  offer: number;

  @Column({type: "int"})
  deal: number;

  @Column({type: "int"})
  revenue: number;

  @Column({type: "timestamp", default: () => "CURRENT_TIMESTAMP"})
  creation_date: string;
}

I have been searching for this issue for two days and have seen that anyone with this issue has not got any answers. @CesarHuelamo is no exception to this fact.

related issues:

related comment:

I know it’s not, but no matter how query was built, final result set can be treated as such. I’ve done it with Hibernate, where I’d write entire query with raw SQL and still get correctly mapped entity and it’s relations.

For example, I think this query should map photos to users:

createQueryBuilder("user")
    .leftJoinAndMapMany(
        "user.photos",
        qb => qb.from(Photo, "photo"),
        "photo",
        "photo.userId = user.id")
    .geMany();

otherwise, what is the purpose of subquery in leftJoinAndMapMany if it can’t be mapped?

_Originally posted by @xxzefgh in https://github.com/typeorm/typeorm/issues/2074#issuecomment-386789509_

The example he is given, where he states that it should map, it does not map.

The answer given by @pleerock:

yeah that shall work however for map many “user.photos” is just a property name, it does not care if its a relation or something else. And btw most of times its really better to execute a separate queries and map the data in terms of both performance and code, so I was thinking to deprecate leftJoinAndMapMany method, maybe it will be in the future.

_Originally posted by @pleerock in https://github.com/typeorm/typeorm/issues/2074#issuecomment-386803563_

“Shall work” but it does not work.

Please clarify this. Is this a bug or is this intended. And when it is intended, the docs are wrong too.

Joining any entity or table

You can join not only relations, but also other unrelated entities or tables. Examples:

const user = await createQueryBuilder("user")
    .leftJoinAndSelect(Photo, "photo", "photo.userId = user.id")
    .getMany();
const user = await createQueryBuilder("user")
    .leftJoinAndSelect("photos", "photo", "photo.userId = user.id")
    .getMany();

When I use this exact code, the getMany() returns no results. On the other hand, the getRawMany(); returns results.

7reactions
Khanjicommented, Jul 8, 2019

@Khanji I said that such behavior is what I expect, but it is not implemented (doesn’t actually work). With that said, I never touched this library since then, so I don’t know what is the current status. of this issue.

@xxzefgh Sorry if I made it sound like you were saying that it worked. My intention was to make it very clear for the typeorm team that it does not work. Because that particular question/bug has never been answered. Thank you for replying.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is it possible to use subquery in leftJoinAndSelect in TypeORM
In docs it's said that "Subqueries are supported in FROM, WHERE and JOIN expressions." but no example is provided. So, i have no...
Read more >
Left join not working with sub-query - DBA Stack Exchange
The inner query works correctly to select the top 5. But the LEFT JOIN in outer query does not select the rows where...
Read more >
Select using Query Builder - typeorm - GitBook
Note: LIMIT may not work as you may expect if you are using complex queries with joins or subqueries. If you are using...
Read more >
SQL — Mistakes using LEFT JOIN, Sub-query and SELECT
1. Use SUM clause in SELECT statement. This could be a solution but the problem is I have to add a long list...
Read more >
[Solved]-Correct use of LEFT JOIN/ON/AND on TypeORM from ...
The problem you ran in is if there is just no case with a certain status, you will never join this status with...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found