Oracle 中的外连接和自引用

发布于 2024-12-02 15:16:32 字数 972 浏览 1 评论 0原文

我有在不同地点签订合同的客户,必须付费。

网站的帐单地址有两种类型:按客户地址收费的网站和按其他地址收费的网站。 站点类型由字段“状态”处理:如果站点在客户地址收费,则该字段等于“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

I have customers with contract at various sites which must be charged.

There are two types of billing address for the sites: sites charged at the customer's address and sites charged to another address.
The kind of site is handled by the field 'status': if the site is charged at the customer's address, the field is equal to 'C'. If it is charged to a different site's address, it is equal to 'A' and the field 'bill_site_id' is filled with the 'site_id' used for billing. I want to retrieve, in one query, the address where I have to send the bill...

Let's say a customer have two sites (the A refers to the B for billing); the request obviously shows the two sites, but I only want the one used for billing (the B).
How to retrieve this one only?

Here is my query (anonymized, so please be gentle :-) )

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心的位置 2024-12-09 15:16:32

我很确定我知道你想要什么,但不能 100% 确定查询中的“ch.status”指的是什么。另外,我不确定从所提供的信息中您是否可以实现您想要的...

希望数据结构在您的控制之下,以便您可以按照您想要的方式设置它。

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

解决这个问题的一种方法是站点表有一个 main_address 标志。 (我认为这是围绕 ch.status 的混淆)

如果站点表上有一个标志那么...

WHERE c.idcompany = cwp.idcompany
AND cwp.site_id = wp.site_id
和 (
(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。

I am pretty sure I know what you want but am not 100% sure what 'ch.status' refers to in the query. Also i am not sure that from the information given you can achieve what you want ...

Hopefully the data structures are under your control so you can set it up how you want.

If I read your specification correctly then I think you want/need only 1 instance of the site table in the query, but it is then not clear how you identify the customer's address.

One way round this is for the site table to have an main_address flag. (I think this is the confusion around ch.status)

If there is a flag on the site table then ...

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

Another way would be to have the Main Adress and Billing addresses as foreign keys on the customer table, and to forget about the status flag so :

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

If this makes no sense then perhaps you can post a DESCRIBE of the tables involved.

你爱我像她 2024-12-09 15:16:32

从技术上讲,联合是两个查询,但您可以在单个命令中运行它,它应该执行您想要的操作,因此我将其作为一个选项扔掉。 :)

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'

我看不到您的表结构,因此可能可以进行更多优化,但我认为这将帮助您指明工作方向。这很可能不会比您现有的查询更快,但它更容易理解。

Technically a Union is two queries, but you can run it in a single command and it should do what you want so I'm throwing it out as an option. :)

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'

I can't see your table structure so it's probably possible to optimize more, but I think that'll help point you in a working direction. This may very well not be any faster then your existing query, but it's a fair bit easier to understand.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文