2015-11-05 29 views
2

我需要帮助来解决这个特定的SQL问题,我不能写存储特效,因为我需要将此端口移植到Hive。加入后从另一个表第二最低值

有两个tQCles Contr和Lvl,我需要左连接它们,并使用前一行的值填充来自LVL的连接tQCle中的空值。 我有样品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) | 

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

for。例如第2行的空值为ACTY_SEQ_NBR,其对应的ACT_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 | 

任何帮助表示赞赏

回答

1

感谢更广泛的例子!这可能适用于单个完整的外连接,但我认为聚合和过滤会变得混乱。最简单的办法是左连接到拉特两次,第一次找到“以前act_seq_nbr”,然后再为你一直(但使用合并使用“以前act_seq_nbr”当没有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 |    
+0

感谢您的试用,但查询无法按预期工作。 MAX不是我需要的,如果LVL表连接的ACTY_SEQ值为空,请从LVL表中查找小于相应CONTR表的ACTY_SEQ值的ACTY_SEQ值。 – Abhi

+1

我与Amninder--你能提供编辑原始问题的样本数据,实际演示所有变化(和每个期望的结果)? – KevinKirkpatrick

0

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

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; 
+0

感谢Amninder的尝试,但没有得到预期的结果。在行#4 ABC5433 |的情况下查询失败2013-04-21 | 00 | 1,其中LVL数据全为空,我们需要从LVL中找到最低的ACTY_SEQ。 w.r.t的值降低或等于其CONTR值。根据查询,即使我们有LVL条目,它也会返回'NA'。 AB56DDF | 1999-10-01 | 14 | 1 – Abhi

0

你想如何处理你所提供的两行以外的例子我不清楚......如果你能在填补空白的数据的其余部分,这将有所帮助。

在此期间,这里有一个裂缝它:

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 
+0

谢谢Hambone。我会多解释一下。在我们对Contr c和LVL l进行LEFT连接后,我们将为l.id,l.eff_dt,l.m_nbr和l.seq_nbr获取空值。对于LVL l为空的所有行,我们需要填充LVL表中的l.acty_seq_nbr值。为此,条件是找到左连接表的a.id,a.eff_dt,a.m_nbr和a.acty_seq_nbr的值,从LV表中找到一个较低或相等的值,例如(来自LVL nl的SELECT nl.acty_seq_nbr,其中a.id = nl.id和a.eff_dt = nl.eff_dt,a.m_nbr = nl.m_nbr和nl.acty_seq_nbr <= a.acty_seq_nbr)。希望这可以帮助 – Abhi

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年4月21日00 1 1 IMC

什么样的数据是你期待的lvl_acty_seq_nbr为ABC614E & ABC5433。 ABC614E在lvl表中没有acty_Seq_nbr,并且在控制中有1 &。请为上面的id提供您的预期输出。你想要在同一个ID内的最低值或所有ID的最低值?

相关问题