查询以合并 Oracle/Teradata 中的后续行
Posted
技术标签:
【中文标题】查询以合并 Oracle/Teradata 中的后续行【英文标题】:Query to Merge subsequent rows in Oracle/Teradata 【发布时间】:2019-08-21 07:38:42 【问题描述】:我有一个表格,数据如下
DB DBMS INST SCHEMA TABLE COLUMN HDFT N_Identity Class
IDS TD SBD IDS Data_Val cust_t HIGH
IDS TD SBD IDS Data_Val cust_t GID
IDS TD SBD IDS Data_Val cust_t Phone
IDS TD SBD IDS Data_Val cust_t Account
IDS TD SBD IDS Data_Val cust_t Visa
IDS TD SBD IDS Data_Val cust_t Mail
IDS TD SBD IDS Data_Val cust_t Email
IDS TD SBD IDS Data_Val cust_t Login Yes
TDS TD FDT TDS Expense Exp_t Name LOW
TDS TD FDT TDS Expense Exp_t Yes
我想要的输出如下:
DB DBMS INST SCHEMA TABLE COLUMN HDFT N_Identity Class
IDS TD SBD IDS Data_Val cust_t GID Yes HIGH
IDS TD SBD IDS Data_Val cust_t Phone Yes HIGH
IDS TD SBD IDS Data_Val cust_t Account Yes HIGH
IDS TD SBD IDS Data_Val cust_t Visa Yes HIGH
IDS TD SBD IDS Data_Val cust_t Mail Yes HIGH
IDS TD SBD IDS Data_Val cust_t Email Yes HIGH
IDS TD SBD IDS Data_Val cust_t Login Yes HIGH
TDS TD FDT TDS Expense Exp_t Name Yes LOW
对于特定列,N_identity 将具有 Yes 或 No 值。到目前为止,我已尝试使用以下查询,但它没有给我想要的结果:
SELECT * FROM
(
SELECT * FROM
(
SELECT DB,DBMS,INST,SCHEMA,TABLE,COLUMN, MAX(HDFT) as HDFT, MAX(N_Identity) as N_Identity, MAX(Class) as Class
FROM Table
GROUP BY DB,DBMS,INST,SCHEMA,TABLE,COLUMN
)a
UNION
SELECT DB,DBMS,INST,SCHEMA,TABLE,COLUMN, HDFT, N_Identity, Class FROM Table
)b
WHERE HDFT IS NOT NULL
AND N_Identity IS NOT NULL
AND Class IS NOT NULL
更新要求: HDFT 值可以为 null,以下是一种情况:
DB DBMS INST SCHEMA TABLE COLUMN HDFT N_Identity Class
IDS TD SBD IDS Data_Val cust_t No INT
IDS TD SBD IDS Data_Val cust_t INT
IDS TD SBD IDS Data_Val cust_t No
预期结果:
DB DBMS INST SCHEMA TABLE COLUMN HDFT N_Identity Class
IDS TD SBD IDS Data_Val cust_t No INT
【问题讨论】:
在什么基础上你想要等级和身份一样高 您能否更详细地描述您想用来确定这些派生列的值的逻辑——N_Identity
和Class
?
我只想要在 N_identity 和 Class 字段中填充的任何值(对于一个特定的列只有一个)。这些值应针对非空 HDFT 列填充,空 HDFT 行应合并/删除。
您的实际预期输出不清楚。您描述中的第一个输出与您在更新部分中提到的第二个输出相矛盾。你能举一个所有场景的例子吗?
【参考方案1】:
我想你需要nvl()
和first_value()
分析函数,只需要考虑在最后一步过滤hdft is not null
(在这些函数完成子查询操作之后):
with tab2 as
(
select db, dbms, inst, schema, "table", "column", hdft,
first_value(class) over (partition by db) as class,
nvl(N_Identity,'Yes') as N_Identity
from tab
)
select * from tab2 where hdft is not null;
Demo
附:避免使用保留关键字来命名表或列,例如table
、column
。
【讨论】:
我通过添加以下内容在 SQL Server 上运行它:over (partition by "database" order by "database" desc) 因为那里需要 order by,但类值对所有的都是 NULL行。另外,我不明白为什么“是”在 nvl 中被硬编码,因为该值也可以是 NO 但是你@user3901666 用oracle
标记了这个问题。其次,我不知道背后的逻辑,你应该详细说明,尤其是N_Identity
专栏。
很抱歉造成混乱,但我可以将其更改为 sql server,因此这不是问题。此外,根据我的数据,HDFT 字段可以为空。所以当前查询不会选择那个。
您的解决方案非常适合我。你能支持我的问题吗?我现在正在执行问题禁令。【参考方案2】:
select db,dbms,inst,schema,table,column,hdft,
case when N_identity>0 then N_Identity else 'Yes' end as N_identity
,case when class>0 then class
when column='cust_t' then 'HIGH'
when column='Exp_t' then 'LOW' end as Class
from table
where hdft>0
【讨论】:
这只是一个示例数据,我需要一个通用查询。您的查询采用了我不需要的硬编码值【参考方案3】:你可以像这样使用 first_value 函数:
with selection as
(
select db, dbms, inst, scheme, table1, column1, hdft,
first_value(Class1) over (partition by db order by Class1) as "class1",
first_value(N_Identity) over (partition by db order by N_Identity) as "N_Identity"
from Y
)
select * from selection where hdft is not null;
【讨论】:
HDFT 字段可以为空。请查看请求的更新说明。以上是关于查询以合并 Oracle/Teradata 中的后续行的主要内容,如果未能解决你的问题,请参考以下文章