根据列比较选择可能包含空值的行

use*_*917 4 db2 select date

给定一个名为 table1 的表,其前几行如下所示:

Idkey DateA     DateB       FieldA    FieldB
1     '2011-06' '2011-03'   20        A
1     '2011-05' '2011-03'   20        A
1     '2011-04' '2011-03'   20        A
1     '2011-03' '2011-03'   20        A
1     '2011-02'  <null>     <null>    <null>
1     '2011-01'  <null>     <null>    <null>
2     '2011-08'  '2011-06'  30        B
2     '2011-07'  '2011-06'  30        B
2     '2011-06'  '2011-06'  30        B
2     '2011-05'  <null>     <null>    <null>
Run Code Online (Sandbox Code Playgroud)

我想从 DateA = DateB 和 DateB 处于 2011 年的那一点开始为唯一的 Idkeys 值选择所有行。也就是说,我想:

Idkey DateA     DateB       FieldA    FieldB
1     '2011-03' '2011-03'   20        A
1     '2011-02'  <null>     <null>    <null>
1     '2011-01'  <null>     <null>    <null>
2     '2011-06'  '2011-06'  30        B
2     '2011-05'  <null>     <null>    <null>
Run Code Online (Sandbox Code Playgroud)

我试过类似的东西:

with subt as (
  select Idkey from table1
  where DateB between '2011-01' AND '2011-12'
  group by Idkey 
  order by 1
)

select Idkey, DateA, DateB, FieldA, FieldB,
from table1 b
join subt 
on subt.Idkey = b.Idkey
where b.DateA <= nvl(DateB,b.DateA);
Run Code Online (Sandbox Code Playgroud)

但它没有给我我想要的。有任何想法吗?

And*_*y M 5

你也可以尝试一个基于window MAX()的解决方案:

WITH
  FirstMatches AS
  (
    SELECT
      *,
      MAX(CASE WHEN DateA = DateB AND DateB BETWEEN '2011-01' AND '2011-12' THEN DateA END)
        OVER (PARTITION BY Idkey) AS FirstDateA
    FROM
      table1
  )
SELECT
  Idkey,
  DateA,
  DateB,
  FieldA,
  FieldB
FROM
  FirstMatches
WHERE
  DateA <= FirstDateA
;
Run Code Online (Sandbox Code Playgroud)

此解决方案假定“开始于”所暗示的行顺序DateA DESCypercube?? 的解决方案相同

请注意,虽然查询将特别在DateB位于 2011 年的行中查找日期匹配的行,但输出可能包括DateA日期早于 2011 年的行。如果您只想获取DateA位于 2011 年的行,您可以将其指定为 CTE 中的 WHERE 过滤器,也可以删除CASE 表达式中不再需要的DateB范围过滤器:

WITH
  FirstMatches AS
  (
    SELECT
      *,
      MAX(CASE WHEN DateA = DateB THEN DateA END)
        OVER (PARTITION BY Idkey) AS FirstDateA
    FROM
      table1
    WHERE
      DateA BETWEEN '2011-01' AND '2011-12'
  )
SELECT
  Idkey,
  DateA,
  DateB,
  FieldA,
  FieldB
FROM
  FirstMatches
WHERE
  DateA <= FirstDateA
;
Run Code Online (Sandbox Code Playgroud)