Based on typeORM docs on using subqueries, there are explained how to create subqueries. Example:
const qb = await getRepository(Post).createQueryBuilder("post");
const posts = qb
    .where("post.title IN " + qb.subQuery().select("user.name").from(User, "user").where("user.registered = :registered").getQuery())
    .setParameter("registered", true)
    .getMany();
But there is no equivalent as to what the SQL would be.
Supposed that I have the query which contains subqueries like the following:
SELECT a, TO_CHAR (MAX (jointable.f), 'MON YYYY') as f,
   t3.c, t3.d, t1.e
FROM table1 t1 
LEFT JOIN table2 t2 ON t2.e = t1.e
JOIN table3 t3 ON t3.d = t2.d
JOIN
 (SELECT f, t4.g, t5.e, t6.h
   FROM table4 t4 
   JOIN table5 t5 ON t4.g = t5.g
   JOIN table6 t6 ON t6.g = t4.g
   AND (t6.i = 2
        OR (t6.i = 1 AND j = 1)
       )
     WHERE t4.k = 4
     ) jointable ON t1.e = jointable.e
WHERE jointable.h = :h
AND(:d = 3 OR 
    t3."d" = :d
   )
GROUP BY a, t3.c, t3.d, t1.e
ORDER BY a ASC
How should I use the typeORM query builder function for the SQL query above?
Assuming that I had created entities related to all table being used on the query above.
A subquery is a query that appears inside another query statement. Subqueries are also referred to as sub- SELECT s or nested SELECT s. The full SELECT syntax is valid in subqueries.
You get these features on our free plan: Unlimited typeforms. 10 questions per typeform. 10 responses per month.
You can use the . loadRelationCountAndMap query method to count elements from your relation. the left join to articles above is not needed for loadRelationCountAndMap . But, you 100% on the mark with loadRelationCountAndMap .
I hope this answer could help others to use TypeORM subquery.
const subquery = await getManager()
    .createQueryBuilder(table4, 't4')
    .select('"t4".f')
    .addSelect('"t4".g')
    .addSelect('"t5".e')
    .addSelect('"t6".h')
    .innerJoin(table5, 't5', '"t4".g = "t5".g')
    .innerJoin(table6, 't6', '"t6".g = "t4".g')
    .where('"t4".k = 4 AND ("t6".i = 2 OR ("t6".i = 1 AND "t6".j = 1))');
  model = await getManager()
    .createQueryBuilder(table1, 't1')
    .select('"t1".a')
    .addSelect("TO_CHAR (MAX (jointable.f), 'MON YYYY')", 'f')
    .addSelect('"t3".c')
    .addSelect('"t3".d')
    .addSelect('"t1".e')
    .leftJoin('table2', 't2', '"t2".e = "t1".e')
    .innerJoin(table3, 't3', '"t3".d = "t2".d')
    .innerJoin('('+subquery.getQuery()+')', 'jointable', '"t1".e = jointable.e')
    .where('jointable.h = :h AND (:d = 3 OR "t3".d = :d)',
      { h: h, d: d })
    .groupBy('"t1".a, "t3".c, "t3".d, "t1".e')
    .orderBy('"t1".a', 'ASC')
    .getRawMany();
I was using '('+subquery.getQuery()+')' for getting the subquery select query as an equivalent to
(SELECT f, t4.g, t5.e, t6.h ....
......
.... ) jointable ON t1.e = jointable.e
Based on what I understand:
Join actually is equal to inner join
.select is and equivalent of select in SQL. You could also add
aliases (as in SQL).
.addSelect is similar to , in select
There are two types of results you can get using select query
builder: entities or raw results. To describe whether you want
the data as entities (getOne and getMany) or what it
is(getRawOne and getRawMany).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With