使用主查询加入记录计数的子查询 - 避免冗余查询

时间:2015-06-04 12:44:52

标签: sql oracle

我有两个表,即Sequence表和Work表。我必须加入它们并从Sequence表中获取Sequence表中每个TN_ID的P_KEY和L_KEY。现在,我还想为每个TN_ID附加{P_KEY,L_KEY}的计数与序列表的每个TN_ID。为此,我必须两次编写序列表和工作表的连接。我想避免这种情况。我怎样才能做到这一点?

Select Distinct
    A.TM_ID, rtrim(A.TN_ID) as TN_ID,  
    W.P_KEY, W.L_KEY
    FROM Sequence_Table A Left Outer JOIN Work_Table W
    ON A.TM_ID=W.TM_ID AND rtrim(A.TN_ID)=rtrim(W.TN_ID)
        
    Join
    
    (SELECT A.TM_ID as TM_ID_c, A.TN_ID as TN_ID_c, count(*) as Count_
    FROM Sequence_Table A LEFT OUTER JOIN Work_Table W
    ON A.TM_ID=W.TM_ID AND rtrim (A.TN_ID) = rtrim (W.TN_ID)
    Group by A.TM_ID, A.TN_ID) C                                     
    On A.TM_ID = C.TM_ID_C and A.TN_ID = C.TN_ID_C

PS:仅使用Oracle SQL而不使用PL / SQL的解决方案。

2 个答案:

答案 0 :(得分:2)

使用with子句来计算子查询因子,请参阅WITH Clause : Subquery Factoring

使用它可以获得更多可读性,并且在大多数情况下可以更快地进行查询。

答案 1 :(得分:1)

正如用户@ 54l3d提到的重复部分代码一样,通常的做法是使用with子句。 对于你的查询它应该是(它给你的结果与你的相同):

with cte as (
  select st.tm_id, rtrim(st.tn_id) tn_id, wt.p_key, wt.l_key
    from sequence_table st left join work_table wt 
      on st.tm_id = wt.tm_id and rtrim(st.tn_id) = rtrim(wt.tn_id))
select distinct a.tm_id, a.tn_id, p_key, l_key 
  from cte a 
  join (select tm_id, tn_id, count(1) cnt from cte group by tm_id, tn_id) c
    on a.tm_id = c.tm_id and a.tn_id = c.tn_id

SQLFiddle

BTW - 我认为你甚至不需要自我加入查询,你可以缩短你的语法:

select distinct st.tm_id, rtrim(st.tn_id) tn_id, wt.p_key, wt.l_key
  from sequence_table st left join work_table wt 
    on st.tm_id = wt.tm_id and rtrim(st.tn_id) = rtrim(wt.tn_id)

...但也许我没有注意到某些内容,或者您​​提供此查询仅作为重复代码的示例。