我有这个简单的 SQL:
SELECT
c.name,
c.planned,
(
SELECT COALESCE(SUM(t.amount), 0)
FROM public.transaction AS t
WHERE t."categoryId" = c.id
) AS actual,
c.type,
c.id,
c."userId"
FROM public.category AS c;
我正在尝试将其转换为 TypeORM 查询:
const allCategories = await categoryRepository
.createQueryBuilder()
.select([
'category.id',
'category.name',
'category.planned',
'category.type',
])
.addSelect((subQuery) => {
return subQuery
.select('COALESCE(SUM(transaction.amount))', 'category.actual')
.from(Transaction, 'transaction')
.where('transaction.categoryId = category.id');
}, 'category.actual')
.where('category.user = :userId', { userId: res.locals.user.id })
.from(Category, 'category')
.getMany();
问题是
actual
字段没有返回,我无法准确地弄清楚我做错了什么。
这是 TypeORM 查询的 SQL 输出:
SELECT
"category"."id" AS "category_id",
"category"."name" AS "category_name",
"category"."planned" AS "category_planned",
"category"."type" AS "category_type",
(
SELECT COALESCE(SUM("transaction"."amount"), 0) AS "category_actual"
FROM "transaction"
WHERE "transaction"."categoryId" = "category"."id"
) AS "category_actual"
FROM
"category"
WHERE
"category"."userId" = $1;
const allCategories = await AppDataSource.createQueryBuilder()
.select('category.id', 'id')
.addSelect('category.name', 'name')
.addSelect('category.planned', 'planned')
.addSelect('category.type', 'type')
.addSelect((subQuery) => {
return subQuery
.select('COALESCE(SUM(transaction.amount), 0)', 'actual')
.from(Transaction, 'transaction')
.where('transaction.categoryId = category.id');
}, 'actual')
.where('category.user = :userId', { userId: res.locals.user.id })
.from(Category, 'category')
.getRawMany();
已修复:
使用
getRawMany()
方法代替getMany()
。请阅读这里这是为什么。本质上,当您需要特定数据时使用后者。
使用
AppDataSource
代替特定存储库。我发现,当使用特定存储库时,我会获得相同数据的副本。这是有道理的,因为我的查询必须超出单个实体。
我使用
addSelect
而不是将它们捆绑到数组中,因为这是向字段添加别名的唯一方法,否则,使用 getRawMany()
时,数据将作为 category_id
返回。