查询以合并 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_IdentityClass 我只想要在 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

附:避免使用保留关键字来命名表或列,例如tablecolumn

【讨论】:

我通过添加以下内容在 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 中的后续行的主要内容,如果未能解决你的问题,请参考以下文章

合并两个查询以获取 SQL 中的合并值

合并两个查询以获取两列中的数据

合并中的内部查询以设置空值

从 MS Access 访问 .mdb 文件中的后端表

DB2 中的合并查询

MYSQL列中的数据以逗号隔开,如何查询?