Oracle SQL - 连接具有特定属性的行
Oracle SQL - Concat rows with specific properties
我写了一个 SQL - 语句将结果导出到 excel sheet 进行分析。
目前我遇到的问题:
Some data which are split in 2 rows but need it as 1 row.
Reason for that is one column, with different values.
我解释结构:
sql 创建这个 table (headers):
ROOT|INSERT_TS|COUNT_ALL|Order_Type|Input_Obj|Input_SUPP|IS_SIM|Last_TS|Status_Type|Count_Open
关于我的问题的示例数据(这是给出我实际 SQL - 声明的结果):
R |In_TS|C_AL|O|I_Obj|I_Supp|IS_Sim|La_TS|Status|C_Opn|
--+-----+----+-+-----+------+------+-----+------+-----+
76|date1|1451|a|file1|mass |1 |date2|work |1451 | <-- 1st part
76|date1|25 |a|file1|mass |1 |date2|final |0 | <-- 2nd part
76|date1|1 |b|file1|man |0 |date2|final |0 |
76|date1|1 |c|file1|mass |1 |date2|work |1 |
最后我想要的是这个(修复sql查询后我的目标):
R |In_TS|C_AL|O|I_Obj|I_Supp|IS_Sim|La_TS|Status|C_Opn|
--+-----+----+-+-----+------+------+-----+------+-----+
76|date1|1476|a|file1|mass |1 |date2|work |1451 | <-- 1 row
76|date1|1 |b|file1|man |0 |date2|final |0 |
76|date1|1 |c|file1|mass |1 |date2|work |1 |
那是我的实际 sql query/statement:
SELECT
distinct t1.ROOT r,
min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
count(distinct t1.tool_ID) c_al, -- this count give the number of modul steps in this "business tool" - no sum task is here needed
t1.ORDERTYPE o,
t1.I_OBJ,
t1.I_Supp,
t1.IS_SIM,
max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
t2.STATUS status,
sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY
t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM, t2.STATUS
ORDER BY 2 desc, 1 desc
;
我通过自己的努力和搜索来解决这个问题:
我在这个社区和 google 中查看了一些关于自己定义函数和 listagg 的任务,但两者都没有帮助,因为 col "Status" 长大了,但是行不合并。
这里有人可以给我解决这个问题的想法吗?
重要的是:
- Col "O" 相同
- Col "R" 相同
- Col "IS_SIM" 相同
- Col "C_AL" 是累积的
- Col "C_Opn" 仅对非 "final" 数据集求和(更好:两个值都是累积的,因为 xx + 0 = xx)
- Col "Status" 仅显示 "work" 值,如果合并行,则删除 "final" 值
解决方案(感谢 ruudvan)
SELECT
distinct t1.ROOT r,
min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
count(distinct t1.tool_ID) c_al, -- this count give the number of modul steps in this "business tool" - no sum task is here needed
t1.ORDERTYPE o,
t1.I_OBJ,
t1.I_Supp,
t1.IS_SIM,
max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
NVL(MAX(case when t2.STATUS != 'final' then t2.STATUS else null end), 'final'), -- i set it to != 'final', because status have more as 1 work value, but i wrote it here for a simple view
sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY
t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM,
ORDER BY 2 desc, 1 desc
;
试试这个:-
SELECT
distinct t1.ROOT r,
min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
sum(distinct t1.tool_ID) c_al,
t1.ORDERTYPE o,
t1.I_OBJ,
t1.I_Supp,
t1.IS_SIM,
max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
t2.STATUS status,
sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM, t2.STATUS
ORDER BY 2 desc, 1 desc;
从这个开始 -
分组依据应该在相同的列上,然后计算其他值。
因此从 GROUP BY 子句中删除 t2.STATUS
。而是替换
SELECT ... t2.STATUS
到
SELECT ... NVL(MAX(case when t2.STATUS = 'work' then t2.STATUS else null end), 'final')
此处 case when t2.STATUS = 'work' then t2.STATUS else null end
将确保同一组中状态为 'final' 的所有值都为空,而 'work' 值将保持原样。对它们执行 MAX
(或 MIN
)将选择非空值,即 'work'.
但是,如果没有 'work' 值:NVL
确保如果所有值都是 'final',那么 MAX()
将导致 null,在这种情况下, return 'final' 作为结果.
SELECT ... COUNT(distinct t1.tool_id) c_al
将保持不变,因为它现在对整个组计数 tool_ids。
我写了一个 SQL - 语句将结果导出到 excel sheet 进行分析。 目前我遇到的问题:
Some data which are split in 2 rows but need it as 1 row. Reason for that is one column, with different values.
我解释结构: sql 创建这个 table (headers):
ROOT|INSERT_TS|COUNT_ALL|Order_Type|Input_Obj|Input_SUPP|IS_SIM|Last_TS|Status_Type|Count_Open
关于我的问题的示例数据(这是给出我实际 SQL - 声明的结果):
R |In_TS|C_AL|O|I_Obj|I_Supp|IS_Sim|La_TS|Status|C_Opn|
--+-----+----+-+-----+------+------+-----+------+-----+
76|date1|1451|a|file1|mass |1 |date2|work |1451 | <-- 1st part
76|date1|25 |a|file1|mass |1 |date2|final |0 | <-- 2nd part
76|date1|1 |b|file1|man |0 |date2|final |0 |
76|date1|1 |c|file1|mass |1 |date2|work |1 |
最后我想要的是这个(修复sql查询后我的目标):
R |In_TS|C_AL|O|I_Obj|I_Supp|IS_Sim|La_TS|Status|C_Opn|
--+-----+----+-+-----+------+------+-----+------+-----+
76|date1|1476|a|file1|mass |1 |date2|work |1451 | <-- 1 row
76|date1|1 |b|file1|man |0 |date2|final |0 |
76|date1|1 |c|file1|mass |1 |date2|work |1 |
那是我的实际 sql query/statement:
SELECT
distinct t1.ROOT r,
min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
count(distinct t1.tool_ID) c_al, -- this count give the number of modul steps in this "business tool" - no sum task is here needed
t1.ORDERTYPE o,
t1.I_OBJ,
t1.I_Supp,
t1.IS_SIM,
max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
t2.STATUS status,
sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY
t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM, t2.STATUS
ORDER BY 2 desc, 1 desc
;
我通过自己的努力和搜索来解决这个问题:
我在这个社区和 google 中查看了一些关于自己定义函数和 listagg 的任务,但两者都没有帮助,因为 col "Status" 长大了,但是行不合并。
这里有人可以给我解决这个问题的想法吗?
重要的是:
- Col "O" 相同
- Col "R" 相同
- Col "IS_SIM" 相同
- Col "C_AL" 是累积的
- Col "C_Opn" 仅对非 "final" 数据集求和(更好:两个值都是累积的,因为 xx + 0 = xx)
- Col "Status" 仅显示 "work" 值,如果合并行,则删除 "final" 值
解决方案(感谢 ruudvan)
SELECT
distinct t1.ROOT r,
min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
count(distinct t1.tool_ID) c_al, -- this count give the number of modul steps in this "business tool" - no sum task is here needed
t1.ORDERTYPE o,
t1.I_OBJ,
t1.I_Supp,
t1.IS_SIM,
max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
NVL(MAX(case when t2.STATUS != 'final' then t2.STATUS else null end), 'final'), -- i set it to != 'final', because status have more as 1 work value, but i wrote it here for a simple view
sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY
t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM,
ORDER BY 2 desc, 1 desc
;
试试这个:-
SELECT
distinct t1.ROOT r,
min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
sum(distinct t1.tool_ID) c_al,
t1.ORDERTYPE o,
t1.I_OBJ,
t1.I_Supp,
t1.IS_SIM,
max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
t2.STATUS status,
sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM, t2.STATUS
ORDER BY 2 desc, 1 desc;
从这个开始 -
分组依据应该在相同的列上,然后计算其他值。
因此从 GROUP BY 子句中删除 t2.STATUS
。而是替换
SELECT ... t2.STATUS
到
SELECT ... NVL(MAX(case when t2.STATUS = 'work' then t2.STATUS else null end), 'final')
此处 case when t2.STATUS = 'work' then t2.STATUS else null end
将确保同一组中状态为 'final' 的所有值都为空,而 'work' 值将保持原样。对它们执行 MAX
(或 MIN
)将选择非空值,即 'work'.
但是,如果没有 'work' 值:NVL
确保如果所有值都是 'final',那么 MAX()
将导致 null,在这种情况下, return 'final' 作为结果.
SELECT ... COUNT(distinct t1.tool_id) c_al
将保持不变,因为它现在对整个组计数 tool_ids。