Внешнее соединение и самостоятельная ссылка в Oracle - PullRequest
0 голосов
/ 01 сентября 2011

У меня есть клиенты с контрактом на различных сайтах, с которых необходимо взимать плату.

Существует два типа платежных адресов для сайтов: сайты, оплачиваемые по адресу клиента, и сайты, оплачиваемые по другому адресу.Тип сайта обрабатывается полем «статус»: если сайт оплачивается по адресу клиента, поле равно «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 голосов
/ 01 сентября 2011

Технически Союз - это два запроса, но вы можете запустить его одной командой, и он должен делать то, что вы хотите, поэтому я выбрасываю его как опцию. :)

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'

Я не вижу структуру вашего стола, поэтому, возможно, можно оптимизировать больше, но я думаю, что это поможет вам указать направление работы. Вполне возможно, что это не будет быстрее, чем ваш существующий запрос, но его немного легче понять.

0 голосов
/ 01 сентября 2011

Я почти уверен, что знаю, что вы хотите, но не уверен на 100%, что в запросе ссылается на ch.status. Также я не уверен, что из предоставленной информации вы можете добиться того, чего хотите ...

Надеемся, что структуры данных находятся под вашим контролем, поэтому вы можете настроить их так, как хотите.

Если я правильно прочитал вашу спецификацию, то я думаю, что вам нужен / нужен только 1 экземпляр таблицы сайта в запросе, но тогда неясно, как вы идентифицируете адрес клиента.

Одним из способов решения этой проблемы является наличие у таблицы сайта флага main_address. (Я думаю, что это путаница вокруг ch.status)

Если на таблице сайта есть флаг, то ...

ГДЕ c.idcompany = cwp.idcompany И 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)

Если это не имеет смысла, возможно, вы можете опубликовать ОПИСАНИЕ задействованных таблиц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...