显示在表中的记录按特定的列

问题描述:

我有一个包含一些数据的两个表的连接和后组:显示在表中的记录按特定的列

表1:ABC

||entity_id| entity_title| cust_code| cust_acc_no  || 
---------------------------------------------------------- 
|| AB101Z | IND  | 101Z | 1234   ||  
|| AB101Z | PAK  | 101Z | 1357   ||  
|| CD101Y | IND  | 101Y | 2468   || 
|| EF101X | IND  | 101X | 3579   ||  
|| JK201N | LKO  | 201N | 5678   || 

表2:高清

||entity_title| in_count| out_quant|| 
--------------------------------------------- 
|| IND  | 10 |  7 ||  
|| LKO  | 7 |  7 ||  
|| PAK  | 5 |  2 || 

加入的表格:abcdef

||entity_id| entity_title| cust_code ||  
-------------------------------------------------- 
|| AB101Z | INDPAK |  101Z || 
|| CD101Y | INDPAK |  101Y ||   
|| EF101X | INDPAK |  101X || 

我想加入表ABC高清这将是表结果ABCDEF

加入这两个表和记录时,将按entity_title分组。加入条件将如此in_count!=out_count。例如,在这种情况下,LKOentity_title不会是结果表的一部分。

我需要用符合条件的entity_title记录替换表示匹配记录的第三条记录,例如,INDPAK是所有记录的替代品,无论这些记录是否适用于IND和PAK两者或其中之一。

我试图想出一个解决方案,但无法形成一个单一的查询。提前感谢任何解决方案建议。

该解决方案避免了硬编码。它包括三个步骤:

  • 第一子查询标识为具有不同计数ENTITY_TITLEs常见(ENTITY_ID,CUST_CODE)组合。

  • 第二个子查询标识拥有这些组合的ENTITY_TITLE并为它们派生一个复合ENTITY_TITLE。 (它使用LISTAGG,它是一个11gR2的东西,但是在早期版本的数据库中有字符串连接的解决方法)。

  • 外部查询生成所需的输出,将复合ENTITY_TITLE替换为原始的ENTITY_TITLE。

这是整件事情。我承认我不喜欢它依赖DISTINCT子句来获得所需的输出,但是加入规则会产生不需要的重复项。

with prs as 
    (select abc.entity_id 
      , abc.cust_code 
     from abc 
      join def 
      on abc.entity_title = def.entity_title 
     where def.in_count != def.out_quant 
     group by abc.entity_id, abc.cust_code having count(*) > 1 
    ) 
    , ent as 
    (select distinct abc.entity_title 
       , listagg(abc.entity_title) 
        within group (order by abc.entity_title) 
        over (partition by prs.entity_id, prs.cust_code) as cmp_entity_title 
     from abc 
      join prs 
    on abc.entity_id = prs.entity_id 
    and abc.cust_code = prs.cust_code 
    ) 
select distinct abc.entity_id 
     , ent.cmp_entity_title 
     , abc.cust_code 
from ent 
    join abc 
    on abc.entity_title = ent.entity_title 
order by abc.entity_id 
     , abc.cust_code 
/

请注意,输出对数据的初始条件强烈依赖。如果您查看我的inevitable SQL Fiddle,您会看到我已将其他行添加到设置中。

第一注释掉ABC纪录......

/* insert into abc values ('AB101Z','BAN','101Z',  5151  ); */ 

..创建一个匹配的三倍,BANINDPAK,它取代BAN,IND或PAK的所有地方。这是您的规则的合乎逻辑的结果,我认为您会期望这一结果。

其他注释掉ABC纪录......

/* insert into abc values ('JK101X','TIB','101K',  3434  ); */ 

...创建第二配对,PAKTIB,它的存在产生了PAK实体的记录多个结果。这也是你的规则的合乎逻辑的结果,但也许是预期不太理想的结果。

+0

感谢您的回复,但不希望输出。查询不包括输出中的下列行: ** CD101Y | \t INDPAK | \t 101Y ** INDPAK将替代所有记录,无论这些记录是针对IND和PAK还是针对这两种记录中的任何一种 – 2014-11-09 19:03:28

select e.entity_id, b.entity_title,e.cust_code 
from abc e inner join def b 
on  e.entity_title=b.entity_title 
where b.in_count!=b.out_count 
group by b.entity_title 
+0

这不会给出预期的结果。 – 2014-11-09 08:30:14

here的东西,可以帮助你:

select * from 
(
    select t1.entity_id, case when t1.entity_title in('IND','PAK') then 'INDPAK' else t1.entity_title end as entity_title, t1.cust_code 
    from abc t1 join def t2 
    on  t1.entity_title = t2.entity_title 
    where t2.in_count <> t2.out_count 

) t 
group by t.entity_id, t.entity_title, t.cust_code 
+0

这只适用于对INDPAK摘要进行硬编码,但看起来不合乎要求。虽然因为这个问题是模糊的,所以它可能是正确的答案:) – APC 2014-11-09 15:01:46

+0

道歉歧义.. :( @ user2315555感谢您的reply.Fiddle显示所需的输出,但参数已被硬编码query.How我将这个查询格式化以去除硬编码 – 2014-11-09 19:02:00

+0

你的意思是你有更多'entity_title'类似于IND/PAK,并且你想连接它们所有的?例如在abc'AB101Z AUS 101Z 1214'中有一个条目,那么你想要得到的结果行为'AB101Z AUSINDPAK 101Z'。 – 2014-11-10 05:30:45