【问题标题】:Second Lowest value from another table after join加入后另一个表的第二个最低值
【发布时间】:2016-02-05 16:35:44
【问题描述】:

我需要帮助来解决这个特定的 sql 问题,我无法编写存储过程,因为我需要将它移植到 Hive。

有两个 tQCles Contr 和 Lvl,我需要将它们左连接并使用前一行的值填充连接的 tQCle 中 LVL 的空值。 我在

中有示例 tQCles
Contr
|      id |     EFF_DT | M_NBR | ACTY_SEQ_NBR | L_CD |
|---------|------------|-------|--------------|------|
| QQFAE46 | 2000-12-24 |    11 |            1 |  POT |
| QQFAE46 | 2000-12-24 |    11 |            2 |  POT |
| QQFAE46 | 2000-12-24 |    11 |            3 |  POT |
| QCC5433 | 2013-04-21 |    00 |            1 |  MIC |
| QCC5433 | 2013-04-21 |    00 |            2 |  MIC |
| QCC614E | 2015-07-18 |    00 |            1 |  MIC |
| QCC614E | 2015-07-18 |    00 |            4 |  MIC |
| QC56DDF | 1999-10-01 |    14 |            2 |  POT |
| QC56DDF | 1999-10-01 |    14 |            3 |  POT |
| QC56DDF | 1999-10-01 |    14 |            4 |  POT |
| ACB3DC2 | 1999-10-01 |    14 |            1 |  POT |

LVL
|      id |     EFF_DT | M_NBR | ACTY_SEQ_NBR | OCCR |
|---------|------------|-------|--------------|------|
| QQFAE46 | 2000-12-24 |    11 |            1 |  100 |
| QQFAE46 | 2000-12-24 |    11 |            3 |  100 |
| QCC5433 | 2013-04-21 |    00 |            2 |  200 |
| QCC614E | 2015-07-18 |    00 |            3 |  200 |
| QC56DDF | 1999-10-01 |    14 |            1 |    0 |

LEFT JOIn of Contr and Lvl

|      id |     EFF_DT | M_NBR | ACTY_SEQ_NBR | L_CD |      id |     EFF_DT |  M_NBR | ACTY_SEQ_NBR |   OCCR |
|---------|------------|-------|--------------|------|---------|------------|--------|--------------|--------|
| QQFAE46 | 2000-12-24 |    11 |            1 |  POT | QQFAE46 | 2000-12-24 |     11 |            1 |    100 |
| QQFAE46 | 2000-12-24 |    11 |            2 |  POT |  (null) |     (null) | (null) |       (null) | (null) |
| QQFAE46 | 2000-12-24 |    11 |            3 |  POT | QQFAE46 | 2000-12-24 |     11 |            3 |    100 |
| QCC5433 | 2013-04-21 |    00 |            1 |  MIC |  (null) |     (null) | (null) |       (null) | (null) |
| QCC5433 | 2013-04-21 |    00 |            2 |  MIC | QCC5433 | 2013-04-21 |     00 |            2 |    200 |
| QCC614E | 2015-07-18 |    00 |            1 |  MIC |  (null) |     (null) | (null) |       (null) | (null) |
| QCC614E | 2015-07-18 |    00 |            4 |  MIC |  (null) |     (null) | (null) |       (null) | (null) |
| QC56DDF | 1999-10-01 |    14 |            2 |  POT |  (null) |     (null) | (null) |       (null) | (null) |
| QC56DDF | 1999-10-01 |    14 |            3 |  POT |  (null) |     (null) | (null) |       (null) | (null) |
| QC56DDF | 1999-10-01 |    14 |            4 |  POT |  (null) |     (null) | (null) |       (null) | (null) |
| ACB3DC2 | 1999-10-01 |    14 |            1 |  POT |  (null) |     (null) | (null) |       (null) | (null) |

现在我需要用值填充来自 LVl tQCle 的空 ACTY_SEQ_NBR 的值。 标准是,从 CONTR(即从加入的 tQCle 的第 4 列)中找到相应的 ACTY_SEQ_NBR,并从 LVL 中找到 ACTY_SEQ_NBR,其中 ACTY_SEQ_NBR 较小 对于相同的 id、eff_dt 和 m_nbr,大于或等于来自 CONTR ACTY_SEQ_NBR 的值。

为了。例如第2行的ACTY_SEQ_NBR为空,对应的Contr ACTY_SEQ_NBR为2,LVL小于2的ACTY_SEQ_NBR值为1。

所以我的理想输出应该是这一行。

|      id |     EFF_DT | M_NBR | ACTY_SEQ_NBR | L_CD |      id |     EFF_DT |  M_NBR | ACTY_SEQ_NBR |   OCCR |
|---------|------------|-------|--------------|------|---------|------------|--------|--------------|--------|
| QQFAE46 | 2000-12-24 |    11 |            1 |  POT | QQFAE46 | 2000-12-24 |     11 |            1 |    100 |
| QQFAE46 | 2000-12-24 |    11 |            2 |  POT |  (null) |     (null) | (null) |            1 | (null) |

I tried a lag query but its not giving correct output for all values.

我执行了 Amniders 查询并更改了结果以获取预期值。 这是我的期望值

|      ID |     EFF_DT | M_NBR | ACTY_SEQ_NBR | L_CD |  LVL_ID | LVL_EFF_DT | LVL_M_NBR | LVL_ACTY_SEQ_NBR |   OCCR | CALC_LVL_ACTY_SEQ_NBR |
|---------|------------|-------|--------------|------|---------|------------|-----------|------------------|--------|-----------------------|
| QQFAE46 | 2000-12-24 |    11 |            1 |  POT | QQFAE46 | 2000-12-24 |        11 |                1 |    100 |                     1 |
| QQFAE46 | 2000-12-24 |    11 |            2 |  POT |  (null) |     (null) |    (null) |           (null) | (null) |                     1 |
| QQFAE46 | 2000-12-24 |    11 |            3 |  POT | QQFAE46 | 2000-12-24 |        11 |                3 |    100 |                     3 |
| QC56DDF | 1999-10-01 |    14 |            2 |  POT |  (null) |     (null) |    (null) |           (null) | (null) |                     1 |
| QC56DDF | 1999-10-01 |    14 |            3 |  POT |  (null) |     (null) |    (null) |           (null) | (null) |                     1 |
| QC56DDF | 1999-10-01 |    14 |            4 |  POT |  (null) |     (null) |    (null) |           (null) | (null) |                     1 |
| QCC5433 | 2013-04-21 |    00 |            1 |  MIC |  (null) |     (null) |    (null) |           (null) | (null) |                   -99 |
| QCC5433 | 2013-04-21 |    00 |            2 |  MIC | QCC5433 | 2013-04-21 |        00 |                2 |    200 |                     2 |
| QCC614E | 2015-07-18 |    00 |            1 |  MIC |  (null) |     (null) |    (null) |           (null) | (null) |                   -99 |
| QCC614E | 2015-07-18 |    00 |            4 |  MIC |  (null) |     (null) |    (null) |           (null) | (null) |                     3 |
| ACB3DC2 | 1999-10-01 |    14 |            1 |  POT |  (null) |     (null) |    (null) |           (null) | (null) |                   -99 |

感谢任何帮助

【问题讨论】:

    标签: mysql sql sql-server oracle hive


    【解决方案1】:

    试试这个:

    SELECT
         ID, EFF_DT, M_NBR, ACTY_SEQ_NBR, L_CD, LVL_ID, LVL_EFF_DT, LVL_M_NBR, LVL_ACTY_SEQ_NBR, OCCR
       ,COALESCE(CASE WHEN LVL_ACTY_SEQ_NBR IS NULL THEN COALESCE(LAG(ACTY_SEQ_NBR) OVER (PARTITION BY ID, EFF_DT, M_NBR ORDER BY ACTY_SEQ_NBR),ACTY_SEQ_NBR) ELSE LVL_ACTY_SEQ_NBR END,'NA') LVL_NMBR
        FROM(
        SELECT A.ID, A.EFF_DT, A.M_NBR, A.ACTY_SEQ_NBR, A.L_CD
        , B.ID LVL_ID, B.EFF_DT LVL_EFF_DT, B.M_NBR LVL_M_NBR, B.ACTY_SEQ_NBR LVL_ACTY_SEQ_NBR , B.OCCR
        FROM EDWT.CONTR A
        LEFT JOIN EDWT.LVL B
        ON A.ID = B.ID AND A.ACTY_SEQ_NBR = B.ACTY_SEQ_NBR and a.eff_dt=b.eff_dt and a.m_nbr=b.m_nbr ) A;
    

    另外,请提供以下行的有效值:

    ID EFF_DT M_NBR ACTY_SEQ_NBR L_CD LVL_ID LVL_EFF_DT LVL_M_NBR LVL_ACTY_SEQ_NBR OCCR LVL_NMBR

    ABC5433 2013-04-21 00 1 IMC 1

    对于 ABC614E 和 ABC5433,您期望 lvl_acty_seq_nbr 的数据是什么。 ABC614E 在 lvl 表中没有 acty_Seq_nbr 并且有 1 和 4in 控制。请提供您对上述 id 的预期输出。您想要相同 id 中的最低值还是所有 id 中最低的值?

    【讨论】:

      【解决方案2】:

      感谢您提供更广泛的示例!这可能通过一个完整的外部连接来实现,但我认为聚合和过滤会变得混乱。最简单的赌注是左加入到 lvl 两次,第一次找到“previous act_seq_nbr”,然后再次像以前一样(但在没有找到 act_seq_nbr 时使用 coalesce 使用“previous act_seq_nbr”):

      SELECT  c.id,c.eff_dt,c.m_nbr,c.acty_seq_nbr, 
              l.id,l.eff_dt,l.m_nbr,
              coalesce(l.acty_seq_nbr, prev_acty_seq_nbr, -99) l_acty_seq_nbr
      from 
          (       
          select c.id,c.eff_dt,c.m_nbr,c.acty_seq_nbr, 
                 MAX(L.acty_seq_nbr) prev_acty_seq_nbr
          from   contr c 
          left join lvl l 
              on 
                  c.id=l.id 
                  and c.eff_dt=l.eff_dt 
                  and c.m_nbr=l.m_nbr 
                  and c.acty_seq_nbr>l.acty_seq_nbr
          GROUP BY   
              c.id,c.eff_dt,c.m_nbr,c.acty_seq_nbr
          ) c
      left join lvl l 
          on 
              c.id=l.id 
              and c.eff_dt=l.eff_dt 
              and c.m_nbr=l.m_nbr     
              and c.acty_seq_nbr=l.acty_seq_nbr;
      

      小提琴: http://www.sqlfiddle.com/#!6/1270f/74/0

      结果:

      |      id |     eff_dt | m_nbr | acty_seq_nbr |      id |     eff_dt |  m_nbr | l_acty_seq_nbr |
      |---------|------------|-------|--------------|---------|------------|--------|----------------|
      | AAFAE46 | 2000-12-24 |    11 |            1 | AAFAE46 | 2000-12-24 |     11 |              1 |
      | AAFAE46 | 2000-12-24 |    11 |            2 |  (null) |     (null) | (null) |              1 |
      | AAFAE46 | 2000-12-24 |    11 |            3 | AAFAE46 | 2000-12-24 |     11 |              3 |
      | AB56DDF | 1999-10-01 |    14 |            2 |  (null) |     (null) | (null) |              1 |
      | AB56DDF | 1999-10-01 |    14 |            3 |  (null) |     (null) | (null) |              1 |
      | AB56DDF | 1999-10-01 |    14 |            4 |  (null) |     (null) | (null) |              1 |
      | ABC5433 | 2013-04-21 |    00 |            1 |  (null) |     (null) | (null) |            -99 |
      | ABC5433 | 2013-04-21 |    00 |            2 | ABC5433 | 2013-04-21 |     00 |              2 |
      | ABC614E | 2015-07-18 |    00 |            1 |  (null) |     (null) | (null) |            -99 |
      | ABC614E | 2015-07-18 |    00 |            4 |  (null) |     (null) | (null) |              3 |
      | ACB3DC2 | 1999-10-01 |    14 |            1 |  (null) |     (null) | (null) |            -99 |            
      

      【讨论】:

      • 感谢您的尝试,但查询未按预期工作。 MAX 不是我需要的,如果 LVL 表连接的 ACTY_SEQ 值为 null ,从 LVL 表中查找 ACTY_SEQ 值小于对应 CONTR 表的 ACTY_SEQ 值。
      • 我支持 Amninder - 您能否提供带有实际演示所有变体(以及每个变体的预期结果)的示例数据的编辑原始问题?
      【解决方案3】:

      我不清楚您希望如何处理您提供的两行之外的示例...如果您可以填写其余数据的空白,那将有所帮助。

      与此同时,这里有一个破解:

      with foo as (
        select
          c.id as cid, c.eff_dt as c_eff_dt,
          c.m_nbr as c_m_nbr, c.acty_seq_nbr as c_acty_seq_nbr,
          l.id as lid, l.eff_dt as l_eff_dt, l.m_nbr as l_m_nbr,
          l.acty_seq_nbr as l_acty_seq_nbr,
          sum (case when l.id is null then 0 else 1 end)
            over (partition by c.id order by c.acty_seq_nbr) as idx
        from
          contr c
          left join lvl l on
            c.id=l.id and 
            c.eff_dt=l.eff_dt and 
            c.m_nbr=l.m_nbr and 
            c.acty_seq_nbr=l.acty_seq_nbr
      )
      select
        cid, c_eff_dt, c_m_nbr, c_acty_seq_nbr,
        lid, l_eff_dt, l_m_nbr, l_acty_seq_nbr,
        min (c_acty_seq_nbr) over (partition by cid, idx) as acty_seq_nbr
      from foo
      

      【讨论】:

      • 谢谢汉伯恩。我再解释一下。在对 Contr c 和 LVL l 进行 LEFT 连接后,我们将获得 l.id、l.eff_dt、l.m_nbr 和 l.seq_nbr 的空值。对于 LVL l 为 null 的所有行,我们需要从 LVL 表中填充 l.acty_seq_nbr 值。为此,条件是找到左连接表的 a.id、a.eff_dt、a.m_nbr,对于 a.acty_seq_nbr 的值,从 LV 表中找到一个较低或相等的值,例如 (SELECT nl.acty_seq_nbr from LVL nl where a.id=nl.id 和 a.eff_dt=nl.eff_dt 和 a.m_nbr=nl.m_nbr 和 nl.acty_seq_nbr
      【解决方案4】:

      我希望我能够理解您的问题。试试这个查询:

       SELECT
       ID, EFF_DT, M_NBR, ACTY_SEQ_NBR, L_CD, LVL_ID, LVL_EFF_DT, LVL_M_NBR, LVL_ACTY_SEQ_NBR, OCCR
       --,LAG(ACTY_SEQ_NMBR) OVER (PARTITION BY ID, EFF_DT, M_NBR ORDER BY ACTY_SEQ_NMBR)
       ,COALESCE(CASE WHEN LVL_ACTY_SEQ_NBR IS NULL THEN LAG(ACTY_SEQ_NBR) OVER (PARTITION BY ID, EFF_DT, M_NBR ORDER BY ACTY_SEQ_NBR) ELSE LVL_ACTY_SEQ_NBR END,'NA') CALC_LVL_ACTY_SEQ_NBR    FROM(
      SELECT A.ID, A.EFF_DT, A.M_NBR, A.ACTY_SEQ_NBR, A.L_CD
      , B.ID LVL_ID, B.EFF_DT LVL_EFF_DT, B.M_NBR LVL_M_NBR, B.ACTY_SEQ_NBR LVL_ACTY_SEQ_NBR , B.OCCR
      FROM EDWT.CONTR A
      LEFT JOIN EDWT.LVL B
      ON A.ID = B.ID AND A.ACTY_SEQ_NBR = B.ACTY_SEQ_NBR and a.eff_dt=b.eff_dt and a.m_nbr=b.m_nbr ) A;
      

      【讨论】:

      • 感谢 Amninder 的尝试,但没有得到预期的结果。 Row#4 ABC5433 | 查询失败2013-04-21 | 00 | 1 LVL 数据全部为空的情况下,我们需要从 LVL 中找到最低的 ACTY_SEQ。 w.r.t 到一个低于或等于其 CONTR 值的值。根据查询,即使我们有一个 LVL 条目,它也会返回“NA”。 AB56DDF | 1999-10-01 | 14 | 1
      猜你喜欢
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 2014-03-03
      相关资源
      最近更新 更多