简体   繁体   English

SQL 改造-DB2

[英]SQL Transformation - DB2

I have a dataset in DB2.我在 DB2 中有一个数据集。 The PK column is PK_Ind and there is a Logic_Ind column as well. PK 列是 PK_Ind,还有一个 Logic_Ind 列。 The transformation I am looking for is for the same PK column if Logic_Ind is NULL then try to find a match where END_DATE of that specific row is BETWEEN START_DATE and END_DATE of any other row for same PK_Ind and Logic_Ind is NOT NULL (ie Logic_Ind='A').如果 Logic_Ind 是 NULL,我正在寻找的转换是针对相同的 PK 列,然后尝试找到一个匹配,其中该特定行的 END_DATE 是相同 PK_Ind 的任何其他行的 START_DATE 和 END_DATE 之间,Logic_Ind 不是 Z6C3E226B4D4795D518ZAB341一个')。 If match found then the values for Col1, Col2 and Col3 should be taken and populated for the row where Logic_Ind is NULL.如果找到匹配项,则应该为 Logic_Ind 为 NULL 的行获取 Col1、Col2 和 Col3 的值并填充。

In the below example 3rd row should find a match with 2nd row and 7th row should match with 4th row and Col1, COl2 and Col3 should reflect the modified values 3rd and 7th row.在下面的示例中,第 3 行应与第 2 行匹配,第 7 行应与第 4 行匹配,并且 Col1、COl2 和 Col3 应反映修改后的第 3 行和第 7 行值。

But if there is no match found then still the same record should be presented as it is in the source dataset.但是,如果没有找到匹配项,则仍应显示与源数据集中相同的记录。

Source dataset:源数据集: 在此处输入图像描述

Target dataset:目标数据集: 在此处输入图像描述

Try this:尝试这个:

SELECT A.PK_IND, A.LOGIC_IND
, NVL2(A.LOGIC_IND, A.COL1, B.COL1) AS COL1
, NVL2(A.LOGIC_IND, A.COL2, B.COL2) AS COL2
, NVL2(A.LOGIC_IND, A.COL3, B.COL3) AS COL3
, A.START_DATE, A.END_DATE
FROM MYTAB A
LEFT JOIN TABLE
(
SELECT B.COL1, B.COL2, B.COL3
FROM MYTAB B
WHERE B.PK_IND = A.PK_IND 
    AND B.LOGIC_IND IS NOT NULL 
    AND A.END_DATE BETWEEN B.START_DATE AND B.END_DATE
FETCH FIRST 1 ROW ONLY  
) B ON A.LOGIC_IND IS NULL;

db<>fiddle example db<>小提琴示例

You can perform an left join with all possible matches (when Logic_Ind is null) and then pick one of them, using ROW_NUMBER() .您可以对所有可能的匹配项执行左连接(当Logic_Ind为空时),然后使用ROW_NUMBER()选择其中一个。

For example, you can do:例如,您可以这样做:

select *
from (
  select
    a.pk_ind,
    a.logic_ind,
    case when a.logic_ind is null then b.col1 else a.col1 end as col1,
    case when a.logic_ind is null then b.col2 else a.col2 end as col2,
    case when a.logic_ind is null then b.col3 else a.col3 end as col3,
    a.start_date,
    a.end_date,
    row_number() over(partition by a.pk_ind, a.start_date 
                      order by b.start_date) as rn
  from t a
  left join t b on b.pk_ind = a.pk_ind
    and a.logic_ind is null
    and b.end_date between a.start_date and a.end_date
) x
where rn = 1

Note : As a side note, for the ROW_NUMBER() function to work as needed, you need to provide a PK for the table.注意:作为旁注,为了让ROW_NUMBER() function 根据需要工作,您需要为表提供 PK。 Since PK_Ind is not a primary key (your data example shows duplicate values), I guessed the tuple ( a.pk_ind , a.start_date ) could act as one.由于PK_Ind不是主键(您的数据示例显示重复值),我猜想元组( a.pk_inda.start_date )可以充当一个。 Change as needed.根据需要进行更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM