我猜这个问题会经常出现,这是我的一些错误步骤和设计缺陷的结果,但是我有点卡住了,而且我也不知道去哪里看,因为我也SQL新手。
此事的基本要点是,我开始使用Sequelize构建应用程序,该程序具有include
函数,该函数本质上将表作为嵌套对象进行连接。但是现在Sequelize对我不起作用,我需要进行原始查询,但是我仍然有依赖于Sequelize给出的结构的应用程序代码。基本上,我需要重新创建Sequelize包含功能,但不是那么冗长。
因此,在详细介绍环境之前,请先进行总结:PostgreSQL和带有Sequelize&Knex的JavaScript(用于以编程方式帮助构建查询)。
所以我有表foo
id | name | bar_id
---+------+-------
1 | Joe | 1
2 | Jan | 2
表bar
id | pet | vet_id
---+-----+-------
1 | cat | 1
2 | dog | 1
表vet
id | name
---+-----
1 | Dr. Elsey
理想的结果如下所示:
id | name | bar.id | bar.pet | bar.vet.id | bar.vet.name
---+------+--------+---------+------------+-------------
1 | Joe | 1 | cat | 1 | Dr. Elsey
2 | Jan | 2 | dog | 1 | Dr. Elsey
Sequelize通过执行以下操作来实现此目的(对select进行释义):
select
foo.id,
foo.name,
bar.id as "bar.id",
bar.pet as "bar.pet",
"bar->vet".id as "bar.vet.id",
"bar->vet".name as "bar.vet.name"
from foo
left outer join bar on foo.bar_id = bar.id
left outer join vet as "bar->vet" on bar.vet_id = vet.id;
是否有任何方法可以不枚举所有这些选择别名?还是我可以尝试更好的输出?
基本上我想构建这样的对象:
{
id: 1,
name: 'Joe',
bar: {
id: 1,
pet: 'cat',
vet: {
id: 1,
name: 'Dr. Elsey'
}
}
};
答案 0 :(得分:1)
我不会将其归类为更容易或更必要的分类(肯定会更复杂),但是如果您真的想避免别名,则可以尝试一些 SQL 元编程使用 Postgres的内置information_schema.columns
表为您生成动态的 SQL 。
与此类似的东西可以满足您的确切需求:
select ' select json_agg(x) from (select '
|| array_to_string(array_agg(table_schema
|| '.' || table_name || '.'
|| column_name || ' as "' || table_schema || '.' || table_name || '.'
|| column_name || '"'), ', ') ||
' from public.foo join public.bar using(id)) as x'
from information_schema.columns
where table_schema = 'public'
and table_name in ('foo', 'bar');
上面的查询将以带有全模式限定列的JSON blob返回每一行。您可以使用Postgres的其他内置JSON functions进行修改以满足您的需求。
注意:在构造这样的查询时,请务必注意 SQL注入的潜力。也就是说,如果最终将脚本中的其他变量插入到此动态生成的SQL中,请务必小心。如果您发现自己需要这样做,则可以将动态SQL包装在您创建的纯SQL函数中,该函数使用绑定变量并将其作为参数,如Bobby Tables网站上所述。>