Как запросить несколько полей базы данных на основе единой структуры - PullRequest
1 голос
/ 13 сентября 2010

В моей базе данных Oracle у меня есть таблица с именем Customers. Есть поля для имени, почтового индекса, города и т. Д., Но есть также поля для invoicename, invoicezip и invoicecity. Для некоторых записей специфичные для счета поля не установлены, и в этом случае метод счета должен использовать информацию из имени, почтового индекса и города.

Сейчас я использую следующий запрос:

select
  case when c.InvoiceName is null then c.Name else c.InvoiceName end as Name,
  case when c.InvoiceName is null then c.Zip  else c.InvoiceZip  end as Zip,
  case when c.InvoiceName is null then c.City else c.InvoiceCity end as City  
  <...>
from
  Customers c
where
  Accountnumber=:accountnumber

Обратите внимание, что проверка выполняется только для InvoiceName. Если это значение установлено, я хочу вернуть все поля, относящиеся к счету, если нет, я хочу вернуть все поля, не относящиеся к счету.

Что бы я хотел бы сделать, это что-то вроде этого

select
  case when c.InvoiceName is not null
    then 
      c.InvoiceName as Name, 
      c.InvoiceZip as Zip, 
      c.InvoiceCity as City
      <...>
    else 
      c.Name, 
      c.Zip, 
      c.City
      <...>
  end
from
  customers c

Есть ли способ сделать это или что-то подобное?

Ответы [ 2 ]

3 голосов
/ 13 сентября 2010

Выражение CASE может возвращать только одно значение, а не 3, поэтому вам нужно 3 выражения CASE. Использование DECODE было бы несколько более кратким, но DECODE зависит от Oracle, тогда как CASE является стандартом ANSI и поэтому предпочтительнее. Но для информации это будет выглядеть так:

select
  decode(c.InvoiceName,null,c.Name,c.InvoiceName) as Name,
  decode(c.InvoiceName,null,c.Zip,c.InvoiceZip) as Zip,
  decode(c.InvoiceName,null,c.City,c.InvoiceCity) as City  
  <...>
from
  Customers c
where
  Accountnumber=:accountnumber

Другая редко используемая, но очень применимая специфичная для Oracle функция - NVL2:

select
  nvl2(c.InvoiceName,c.InvoiceName,c.Name) as Name,
  nvl2(c.InvoiceName,c.InvoiceZip,c.Zip) as Zip,
  nvl2(c.InvoiceName,c.InvoiceCity,c.City) as City  
  <...>
from
  Customers c
where
  Accountnumber=:accountnumber
0 голосов
/ 13 сентября 2010

Я думаю, вам нужна функция COALESCE , чтобы очистить ваш оператор выбора. Это займет первое ненулевое значение в списке.

select 
  coalesce(c.InvoiceName, c.Name) Name, 
  coalesce(c.InvoiceZip, c.Zip) Zip, 
  coalesce(c.InvoiceCity, c.City) City 

РЕДАКТИРОВАТЬ: Шахкальпеш
Я предполагаю, что поля с Invoice в нем будут NULL, когда InvoiceName NULL.

select 
  coalesce(c.InvoiceName, c.Name) Name, 
  coalesce(c.InvoiceName, c.Zip, c.InvoiceZip) Zip, 
  coalesce(c.InvoiceName, c.City, c.InvoiceCity) City 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...