Oracle中的外部联接和自我引用

时间:2011-09-01 14:33:12

标签: oracle outer-join self-join

我的客户在各个网站都有合同,必须收取费用。

网站有两种类型的帐单邮寄地址:在客户地址收费的网站和向其他地址收费的网站。 该类型的站点由字段“status”处理:如果站点在客户的地址收费,则该字段等于“C”。如果向其他网站的地址收费,则其等于“A”,字段“bill_site_id”则填充用于结算的“site_id”。我想在一个查询中检索我必须发送账单的地址......

假设客户有两个站点(A表示B用于计费);请求显然显示了两个站点,但我只想要用于计费的站点(B)。 如何只检索这个?

这是我的查询(匿名,所以请温柔:-))

SELECT CASE wp.status
      WHEN 'A'
         THEN wp2.name
      ELSE c.NAME
   END AS NAME,
   CASE wp.status
      WHEN 'A'
         THEN wp2.adress
      ELSE c.street
   END AS street,
   CASE wp.status
      WHEN 'A'
         THEN wp2.city
      ELSE c.city
   END AS city,
   CASE wp.status
      WHEN 'A'
         THEN wp2.postcode
      ELSE c.postcode
   END AS postcode
FROM customer c, site wp, site wp2, customer_site cwp
WHERE c.idcompany = cwp.idcompany
    AND cwp.site_id = wp.site_id
    AND wp2.site_id(+) = wp.bill_site_id
    AND c.idcompany = :someId
GROUP BY wp.status,
     wp2.name,
     wp2.adress,
     wp2.city,
     wp2.postcode

2 个答案:

答案 0 :(得分:0)

我很确定我知道你想要什么,但我不确定'ch.status'在查询中引用了什么。此外,我不确定从给出的信息中你可以实现你想要的......

希望数据结构在您的控制之下,以便您可以根据需要进行设置。

如果我正确地阅读了您的规范,那么我认为您在查询中只需要/需要1个网站表实例,但是不清楚如何识别客户的地址。

此方法的一个方法是使站点表具有main_address标志。 (我认为这是围绕ch.status的混乱)

如果网站表上有标志,那么......

WHERE c.idcompany = cwp.idcompany     AND cwp.site_id = wp.site_id     AND(           (C.STATUS ='C'和WP.MAIN_ADDRESS = 1)或           (C.STATUS ='A'和WP.SITE_ID = C.BILL_SITE_ID)         )

另一种方法是将主要地址和结算地址作为客户表上的外键,并忘记状态标志,以便:

WHERE WP.SITE_ID = DECODE(C.BILLING_ADDRESS,NULL,C.MAIN_ADDRESS,C.BILLING_ADDRESS)

如果这没有意义,那么也许您可以发布所涉及的表的DESCRIBE。

答案 1 :(得分:0)

从技术上讲,联盟是两个查询,但你可以在一个命令中运行它,它应该做你想要的,所以我把它作为一个选项扔掉。 :)

SELECT c.Name AS NAME, c.street AS STREET, c.city AS CITY, c.postcode AS postcode
FROM customer c
INNER JOIN customer_site cwp ON c.idcompany = cwp.idcompany
INNER JOIN site wp ON cwp.site_id = wp.site_id
WHERE c.idcompany = :someid AND wp.status = 'C'
UNION
SELECT wp2.name AS NAME, wp2.adress AS STREET, wp2.city AS CITY, wp2.postcode AS postcode
FROM customer c
INNER JOIN customer_site cwp ON c.idcompany = cwp.idcompany
INNER JOIN site wp ON cwp.site_id = wp.site_id
INNER JOIN site wp2 ON wp.bill_site_id = wp2.site_id
WHERE c.idcompany = :someid AND wp.status = 'A'

我无法看到你的桌面结构,因此可能有更多的优化,但我认为这有助于指明你的工作方向。这可能不会比现有查询快得多,但它更容易理解。