oracle 在键/值表中高效地展平一对多关系以进行单值查找

pwuypxnk  于 2023-08-04  发布在  Oracle
关注(0)|答案(2)|浏览(89)

我有一个多对一的关系,如下所示:

活动表

| 活动类型|时间戳| Timestamp |
| --|--| ------------ |
| 账号|2019 - 09 - 21 10:00:00| 07/09/2021 |
| 账号|2019 - 09 - 21 10:00:00| 07/09/2021 |
| 图书|2019 - 09 - 21 10:00:00| 07/09/2021 |
| 图书|2019 - 09 - 21 10:00:00| 07/09/2021 |

活动明细表

| ColumnId|新闻资讯|旧值| OLDVALUE |
| --|--|--| ------------ |
| 科目编号|“一二三四五六”|“0123”| "0123" |
| 账户名称|“新名称”|“旧名”| "Old Name" |
| 会计角色|“管理员”|[空]| [NULL] |
| 加入收藏|一百二十三|[空]| [NULL] |
我希望能够回答以下问题:
2021年7月9日有多少个帐号更新,以及已更新的(新)帐号是什么?
我想象的解决方案看起来像这样:
| 活动类型|时间戳|新帐户编号|新帐户名称|新角色| NewRole |
| --|--|--|--|--| ------------ |
| 账号|2019 - 09 - 21 10:00:00|“一二三四五六”|“新名称”|“管理员”| "Admin" |
| 图书|2019 - 09 - 21 10:00:00| [空]|[空]|[空]| [NULL] |
我一直在努力寻找资源来解决这个问题的部分原因是我不知道这种类型的关系被称为什么。
我希望能有一个具体的例子来说明我在这种情况下会使用的SQL,但是如果有人能改进我的词汇量,这样我就可以更有效地自己研究了,那就太好了。
谢谢你的好意

thigvfpy

thigvfpy1#

您的活动详细信息表称为键/值表。也就是说,每个属性没有一个列(old_acoount,new_account,old_name,new_name,...),而是一个键列(columnid)和一个值列(实际上有两个:旧值和新值)。
键/值表并不容易使用。查询它们的数据通常是通过条件聚合(聚合函数中的一个条件)完成的:

select
  a.activityid,
  a.activitytype,
  a.timestamp,
  max(case when columnid = 'AcctNbr' then oldvalue end) as old_account,
  max(case when columnid = 'AcctNbr' then newvalue end) as new_account,
  max(case when columnid = 'AcctName' then oldvalue end) as old_name,
  max(case when columnid = 'AcctName' then newvalue end) as new_name,
  max(case when columnid = 'AcctRole' then oldvalue end) as old_role,
  max(case when columnid = 'AcctRole' then newvalue end) as new_role
from activity a
left join activity_detail ad on ad.activityid = a.activityid
where a.timestamp >= date '2021-09-07' and a.timestamp < date '2021-09-08'
group by a.activityid, a.activitytype, a.timestamp
order by a.activityid;

字符串
(We只想按activityid分组并显示活动的数据。但是Oracle也要求我们按activitytype和timestamp分组,尽管它们在功能上依赖于activityid。Oracle还不能检测到这一点,所以在这方面他们不符合SQL标准。

dojqjjoe

dojqjjoe2#

下面是一些你应该看看的东西。您可以使用pivot/case语句来完成所需的操作
https://stackoverflow.com/a/13160314/12176950

相关问题