sql - 如何在不使用 SQL 中的多个连接条件的情况下获取同一行中的所有值?
问题描述
我有下表结构
学生
Stud_ID | First_Name | Last_name | Contact
ID001 | AAA | AAA | 111
ID002 | BBB | BBB | 222
螺柱用户
Stud_ID | NUM | Value
ID001 | 10 | English
ID001 | 20 | Math
ID001 | 30 | Science
ID002 | 10 | English
ID002 | 20 | Math
预期产出
Stud_id | First_name | 10 | 20 | 30
ID001 | AAA | English | Math | Science
ID002 | BBB | English | Math |
我正在使用的当前查询
select
stud_id,
First_name,
EG.EGUV AS "10",
LE.LEUV AS "20",
FPS.FPSUV AS "30"
from
student,
(SELECT STUD_ID AS EGS,USER_VALUE AS EGUV FROM STUD_USER WHERE COL_NUM='10') AS EG,
(SELECT STUD_ID AS BUS,USER_VALUE AS BUUV FROM STUD_USER WHERE COL_NUM='20') AS BU,
(SELECT STUD_ID AS AUS,USER_VALUE AS AUV FROM STUD_USER WHERE COL_NUM='30') AS A
where
ST.STUD_ID=EG.EGS(+) and
ST.STUD_ID=BU.BUS(+) and
ST.STUD_ID=A.AUS(+)
请让我知道是否有任何其他优化方式来获取所有用户值。 注意:此表结构不能更改,只有读取权限可用
解决方案
您可以为此使用 Oracle PIVOT子句。它将(某种程度上)根据所选列的值动态创建附加列。
这是我使用的查询(使用WITH子句模拟您的输入数据):
WITH
Student
AS
(SELECT 'ID001' AS Stud_ID, 'AAA' AS First_Name, 'AAA' AS Last_name, 111 AS Contact FROM DUAL
UNION ALL
SELECT 'ID002', 'BBB', 'BBB', 222 FROM DUAL),
StudUser
AS
(SELECT 'ID001' AS Stud_ID, 10 AS NUM, 'English' AS VALUE FROM DUAL
UNION ALL
SELECT 'ID001', 20, 'Math' FROM DUAL
UNION ALL
SELECT 'ID001', 30, 'Science' FROM DUAL
UNION ALL
SELECT 'ID002', 10, 'English' FROM DUAL
UNION ALL
SELECT 'ID002', 20, 'Math' FROM DUAL),
Prepare
AS
(SELECT ST.STUD_ID,
ST.FIRST_NAME,
SU.NUM,
SU.VALUE
FROM STUDENT ST LEFT JOIN STUDUSER SU ON ST.STUD_ID = SU.STUD_ID)
SELECT *
FROM Prepare PIVOT (MIN (VALUE) FOR NUM IN (10, 20, 30))
PIVOT函数需要一个聚合函数,因为它将遍历所有结果,例如STUD_ID = ID001 and NUM = 10
,并将根据使用的聚合函数返回一个值。您的示例意味着StudUserSTUD_ID and NUM
表的组合将是唯一的,因此大多数 Oracle 的聚合函数都可以,因为它们只需要遍历一个值。如果组合不是唯一的,您将不得不花一点时间考虑您想要聚合它们的方式。
pivot子句的FOR部分允许您指定要将哪些值转换为列。不幸的是,这不能动态生成,例如:
SELECT *
FROM Prepare PIVOT (MIN (VALUE) FOR NUM IN ( SELECT DISTINCT NUM FROM StudUser ))
那将是无效的并且不会编译。
您还可以为透视列指定所需的列名,如下所示:
SELECT *
FROM Prepare PIVOT (MIN (VALUE) FOR NUM IN (10 Subject1, 20 Subject2, 30 Subject3))
我只是通过搜索找到了PIVOT子句:oracle turn values into columns,所以我猜你没有找到它,因为你不知道如何调用它。不能怪你。
推荐阅读
- android - 小吃店 - 不能在小吃店设置边距
- javascript - 点击事件页面滚动
- keycloak - 如何在 keycloak 中导入多个领域?
- android - RecyclerView 高度限制
- ios - 如何在 Swift UI 中获取过滤列表的索引?
- python - 使用现有的 freeze_interface_graph.pb 和 label_map.pbtxt 部署 TFX
- c# - 结合两个选择语句从数据库中获取数据
- typescript - 如何在 TypeScript 中访问对象键的键?
- c# - 正则表达式匹配广泛?
- python - 如何在 Pandas 中优化/替换这 2 个嵌套的 While 循环