【问题标题】:subquery 2, subquery 3 not seeing main select子查询 2,子查询 3 没有看到主选择
【发布时间】:2015-09-10 19:16:43
【问题描述】:

我有以下代码查询两个数据库(相同的架构,绑定到相同的应用程序)。一个数据库保存服务信息,以及与服务相关的其他事务。选择在事务数据库中运行。 “文件/消息的数量”之前的输出是正确的,但是之后的选择返回一个独立的值并且不考虑主选择。什么是解决方法或正确方法来实现查询 3 的相同,因为它适用于主选择。我也包括了输出。谢谢。

select distinct tctc_cntipcli as "Type of contract" ,tctc_cncclipu as "Contract number", tctc_cndocidc as "Client name", 
 tsrv_cndesser as "Service name", tsrv_cncveser as "Service number", tsrs_cnsubsdc as "Subservice name", tsrs_cnsubser as "Subservice name", tmap_cndesc as "Map" 
 , 
        (select count(tlof_cnlofrid)
        from service.kndtlof
        where tlof_cncclipu = tctc_cncclipu
        and tlof_cnservic = tsrv_cncveser
        and tlof_cnsubser = tsrs_cnsubser
        and tlof_cnfhalta > trunc (sysdate, 'mm')
                            ) as "Volume of files/messages"
                            ,
                            (select count(app_data_id)
                            from app_data ad, status ss, internal_transactions it, service.kndtexe ke, service.kndtctc kc, service.kndtsrv kv, service.kndtsrs ks
                            where ad.int_tran_id = ss.int_tran_id
                            and ss.int_tran_id = it.int_tran_id
                            and
                            (
                              (it.credit_acct = ke.texe_cnasupro)
                            or
                              (it.debit_acct = ke.texe_cnasupro)
                            )
                            and ke.texe_cncclipu = kc.tctc_cncclipu
                            and ke.texe_cnfuncid = kv.tsrv_cncveser
                            and ke.texe_cnsubser = ks.tsrs_cnsubser
                            and ad.entry_timestamp > trunc (sysdate, 'mm')

                            ) as "Volume of Payments"

                          from service.kndtctc, service.kndtexe, service.kndtscm, service.kndtsrv, service.kndtsrs, service.kndtmap
                          where tctc_cncclipu = texe_cncclipu
                          and texe_cnfuncid = tsrv_cncveser
                          and texe_cnfuncid = tsrs_cncveser
                          and texe_cnsubser = tsrs_cnsubser
                          and texe_cncclipu = tscm_cncontra
                          and tscm_cnmapco = tmap_cnmapco
                          and tscm_cnservic = tsrv_cncveser
                          and tscm_cnsubser = tsrs_cnsubser
                          and tctc_cnestado in ('01', '03')
                          and texe_cnestado in ('01', '03')
                          and tscm_cnestado in ('01', '03')
                          and tsrv_cnestado in ('01', '03')
                          and tsrs_cnestado in ('01', '03')
                          and tmap_cnestado in ('01', '03')
                          order by tctc_cncclipu
                          ;

还有输出:

Type of contract||Contract number||Client name||Service name||Service number||Subservice name||Subservice number||Map||Volume of files/messages||Volume of Payments
C  50008753 Change Name  ACH  3085  ACH_IN1  I1  Sungard 820 ACH  31  16884 
C  50008753 Change Name  ACH  3085  ACH_IN4  I4  Sungard 820 ACH  0   16884 
C  50008753 Change Name  ACH  3085  ACH_OUT1 O1  827 NOC and Ret  1   16884 
C  50008753 Change Name  ACH  3085  ACH_OUT4 O4  827 NOC and Ret  0   16884 

另外,我可以使用 max 函数使重复字段只在输出中出现一次吗?根据排序,这些最多可能是主选择中的前 5 个元素。 感谢您的宝贵时间!

【问题讨论】:

  • 您的第二个问题不够清楚,我无法提供任何建议。预期输出与显示的当前输出有什么关系?

标签: sql oracle select subquery


【解决方案1】:

标识为“Volume of Payments"”的第二个标量子查询与外部查询不相关,这与标识为与外部查询相关的"Volume of files/messages" 的第一个标量子查询不同。

您可以通过删除额外的 service.* 表引用来关联您的第二个标量子查询,并改为使用相关值。

在执行此操作时,您的子查询:

,(SELECT COUNT( app_data_id )
     FROM app_data ad
        , status ss
        , internal_transactions it
        , service.kndtexe ke
        , service.kndtctc kc
        , service.kndtsrv kv
        , service.kndtsrs ks
    WHERE ad.int_tran_id   = ss.int_tran_id
    AND ss.int_tran_id     = it.int_tran_id
    AND(( it.credit_acct   = ke.texe_cnasupro )
    OR( it.debit_acct      = ke.texe_cnasupro ) )
    AND ke.texe_cncclipu   = kc.tctc_cncclipu
    AND ke.texe_cnfuncid   = kv.tsrv_cncveser
    AND ke.texe_cnsubser   = ks.tsrs_cnsubser
    AND ad.entry_timestamp > TRUNC( sysdate, 'mm' )
  ) AS "Volume of Payments"

将被转换成这个子查询:

,(SELECT COUNT( app_data_id )
     FROM app_data ad
        , status ss
        , internal_transactions it
    WHERE ad.int_tran_id   = ss.int_tran_id
    AND ss.int_tran_id     = it.int_tran_id
    AND(( it.credit_acct   = texe_cnasupro )  -- <= These two predicates correlate 
    OR( it.debit_acct      = texe_cnasupro ) )-- <= your subquery to the outer query
    AND ad.entry_timestamp > TRUNC( sysdate, 'mm' )
  ) AS "Volume of Payments"

如果上述查询的粒度错误,您可以通过调整外部查询中用于关联标量子查询的列来进行调整。

对您的原始查询的进一步审查表明,我选择用于关联标量子查询的 service.kndtexe.texe_cnasupro 列未在您的外部查询中使用,但是这三列:

  • service.kndtctc.tctc_cncclipu
  • service.kndtsrv.tsrv_cncveser
  • service.kndtsrs.tsrs_cnsubser

是。所以试试这个:

(SELECT COUNT( app_data_id )
   FROM app_data ad
      , status ss
      , internal_transactions it
      , service.kndtexe ke
  WHERE ad.int_tran_id   = ss.int_tran_id
  AND ss.int_tran_id     = it.int_tran_id
  AND(( it.credit_acct   = ke.texe_cnasupro )
  OR( it.debit_acct      = ke.texe_cnasupro ) )
  AND ke.texe_cncclipu   = tctc_cncclipu -- <= Correlate with these three values
  AND ke.texe_cnfuncid   = tsrv_cncveser -- <= similarly to the other sub query
  AND ke.texe_cnsubser   = tsrs_cnsubser -- <= "Volume of files/messages"
  AND ke.texe_cnestado IN( '01', '03' )  -- Plus this filter?
  AND ad.entry_timestamp > TRUNC( sysdate, 'mm' )
) AS "Volume of Payments"

【讨论】:

  • 谢谢哨兵。我认为它的相关性还不是很完美,因为现在我在“支付量”查询上得到了倍数,这使得外部查询上的不同之处不起作用。
  • 再次感谢 Sentinel。不幸的是,输出仍然与我的预期不一致。我添加了您的编辑,但我认为我需要将“支付量”“过滤”到地图级别,因此我连接了另一个与地图表相关联的表,结果仍然存在偏差。请看下面...
  • AND ke.texe_cncclipu = tctc_cncclipu AND ke.texe_cnfuncid = tsrv_cncveser AND ke.texe_cnsubser = tsrs_cnsubser AND ke.texe_cncclipu = tscm_cncontra AND km.tscm_cnmapco = tmap_cnmapco
  • 或许你只需要在子查询AND ke.texe_cnestado IN( '01', '03' )中加入如下谓词,这样你就只统计符合这个要求的记录了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
相关资源
最近更新 更多