SQL - 数据库表映射器 - 基于选择和连接插入表

Posted

技术标签:

【中文标题】SQL - 数据库表映射器 - 基于选择和连接插入表【英文标题】:SQL - Database table mapper - Insert into table, based on select and joins 【发布时间】:2021-04-01 07:30:21 【问题描述】:

这是一个生活中的问题示例,因此您可以更好地了解我们需要什么。

示例

我们有 3 张桌子

cars
*id
*description

car_spec
*id
*car_id
*spec_id
*amount

specs
*id
*name

对于我们想要保留这些数据的每个汽车项目:

*id
*description

以及位于“specs”表中的 3 个“spec”值,基于“car_spec”表:

doors
pistons
hp

我们想像这样将所有需要的数据合并到一个表中。

car_db
*id
*description
*original_car_id
*doors
*pistons
*hp

样本数据

汽车表

id | description
1  | 2020 car 1
2  | 2020 car 2
3  | 2020 car 3

汽车规格表

id | car_id | spec_id | amount
1  | 1      | 1       | 2
2  | 1      | 2       | 12
3  | 1      | 3       | 550
4  | 2      | 1       | 4
5  | 2      | 2       | 4
6  | 2      | 3       | 250

规格表

id | name
1  | doors
2  | pistons
3  | hp

样本结果表

id | description | original_car_id | doors | pistons | hp
1  | 2020 car 1  | 1               | 2     | 12      | 550
2  | 2020 car 2  | 2               | 4     | 4       | 250
3  | 2020 car 3  | 3               | 4     | 8       | 400

我们需要什么

我们需要导出一个包含所需数据的新表。

我们可以在 sql 中执行此操作吗? 如果没有,有什么建议可以告诉我们怎么做?

【问题讨论】:

我认为样本数据和期望的结果会有所帮助——适当的数据库标签也会有所帮助。 @GordonLinoff 我已经添加了示例数据。看看 【参考方案1】:

您通常会使用条件聚合来调整规范。以下语法几乎适用于所有数据库:

select c.id, 
    max(case when s.name = 'doors' then cs.amount end) as doors,
    max(case when s.name = 'pistons' then cs.amount end) as pistons,
    max(case when s.name = 'hp' then cs.amount end) as hp
from cars c
inner join car_spec cs on cs.car_id = c.id
inner join specs s on s.id = cs.spec_id
group by c.id

【讨论】:

感谢您的回答!我已经更改了“我们需要什么”部分。如果需要,请查看并更新您的答案!再次感谢! @jon:查询看起来不错。如果您愿意,可以将c.description 添加到select 子句中。 好的,再次感谢!请你解释一下,为什么我们需要 max 函数呢?据我了解,我们应该只需要“案例”,所以我们可以通过使用“as”来获得我们需要的东西。 @jon:我们希望每辆车有一排,所以我们需要聚合。然后MAX() 只是在每个组中选择相关值。我们可以使用MIN(),结果是一样的。 在大约 750 万行上使用它的性能如何?【参考方案2】:

如果'specs'表是固定的,你可以使用这样的子查询:

select c.id, c.description, c.id as original_car_id,
  (select d.amount from car_spec d where d.car_id = c.id and d.spec_id = 1) as doors,
  (select d.amount from car_spec d where d.car_id = c.id and d.spec_id = 2) as pistons,
  (select d.amount from car_spec d where d.car_id = c.id and d.spec_id = 3) as hp
from cars c;

【讨论】:

以上是关于SQL - 数据库表映射器 - 基于选择和连接插入表的主要内容,如果未能解决你的问题,请参考以下文章

mybatis之映射器(select)

怎么在sql数据库插入记录?

将数据上传/插入到 HDFS 时是不是涉及映射器减速器?

MyBatis sql映射器 Mapper

MyBatis映射器总结

SQL映射器Mapper接口(MyBatis)