如何基于单个案例结构查询多个数据库字段

时间:2010-09-13 10:43:30

标签: sql oracle

在我的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 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:0)

我认为你需要COALESCE函数来清理你的select语句。它将采用列表中的第一个非空值。

select 
  coalesce(c.InvoiceName, c.Name) Name, 
  coalesce(c.InvoiceZip, c.Zip) Zip, 
  coalesce(c.InvoiceCity, c.City) City 
编辑:shahkalpesh
我假设当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