Sql Oracle-使用另一列中的值填充列中的空值

Sql Oracle-使用另一列中的值填充列中的空值,sql,null,obiee,Sql,Null,Obiee,我使用的是Oracle 11.1.1.9.0,我的目标是用每个产品(即产品列中的A、B和C)在“原材料”列中的第一个非空值填充空值。本请求末尾说明了示例表和预期结果 以下代码集均不起作用: 
 代码1: IFNULL(Raw Materials, First_value(Raw Materials) OVER (PARTITION BY Product)) 
 代码2: IFNULL(Raw Materials,  First_value(Raw Material

我使用的是Oracle 11.1.1.9.0,我的目标是用每个产品(即产品列中的A、B和C)在“原材料”列中的第一个非空值填充空值。本请求末尾说明了示例表和预期结果

以下代码集均不起作用: 


代码1:

IFNULL(Raw Materials,
       First_value(Raw Materials) OVER (PARTITION BY Product))

代码2:

IFNULL(Raw Materials, 
        First_value(Raw Materials) OVER (PARTITION BY Product 
                       RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW))

代码3:

COALESCE(lag(Raw Materials ignore null) OVER (partition by Product), 
         Raw Materials)
代码4:

IFNULL(原材料,评估('LAG(%1,1)超过(按%2划分)'作为varchar2(20),原材料,产品))

注意:IFNULL函数在环境中不起作用。使用IFNULL(原材料,“1”)对其进行测试,结果是所有的null值在原材料列中变为1

多谢各位

+---------+----------+ +---------+----------+ | product | material | | product | material | +---------+----------+ +---------+----------+ | A | | | A | Apple | | A | | | A | Apple | | A | | | A | Apple | | A | | | A | Apple | | A | Apple | | A | Apple | | B | | | B | Orange | | B | | | B | Orange | | B | | => | B | Orange | | B | | | B | Orange | | B | Orange | | B | Orange | | C | | | C | Banana | | C | | | C | Banana | | C | | | C | Banana | | C | | | C | Banana | | C | Banana | | C | Banana | +---------+----------+ +---------+----------+ Left is the example table data. Right is the intended result. +---------+----------+ +---------+----------+ |产品|材料|产品|材料| +---------+----------+ +---------+----------+ |苹果| |苹果| |苹果| |苹果| |苹果| |B | | | B |橙色| |B | | | B |橙色| |橙色| |B | | | B |橙色| |橙色| |香蕉| |香蕉| |香蕉| |香蕉| |香蕉| +---------+----------+ +---------+----------+ 左边是示例表数据。正确是预期的结果。 下面的链接“Oracle代码环境”显示了Oracle逻辑SQL函数的代码环境和示例。


Oracle逻辑SQL手册:

对于您的数据集,您只需执行一个窗口
MAX()
MIN()

如果您有一个列可用于对行进行排序(我假设
id
),则可以将
LAG()
忽略null
子句一起使用:

NVL(Raw_Materials, LAG(Raw_Materials IGNORE NULLS) OVER(PARTITION BY Product ORDER BY id))

您可以尝试下面的查询,我们正在使用第一个值分析函数nullif、COALESCE等在行级别而不是列级别上工作

with temp as (select 'A' product,NULL raw_material from dual union all
select 'A',NULL from dual union all
select 'A',NULL from dual union all
select 'A',NULL from dual union all
select 'A','APPLE' from dual union all
select 'B',NULL from dual union all
select 'B',NULL from dual union all
select 'B',NULL from dual union all
select 'B',NULL from dual union all
select 'B','ORANGE' from dual union all
select 'C',NULL from dual union all
select 'C',NULL from dual union all
select 'C',NULL from dual union all
select 'C',NULL from dual union all
select 'C',NULL from dual union all
select 'C','Banana' from dual)
select   a.*,FIRST_VALUE(raw_material IGNORE NULLS) 
     OVER (partition by product ORDER BY product) first_product from temp a;

Oracle没有
IFNULL
函数。如果您在前两个代码段中的任意一个中将
IFNULL
替换为
COALESCE
,则您的代码会正常工作:

选择t.*,
结合(
原材料,
第一个价值(原材料)
忽略空值
超过(按产品划分)
)作为更新的原材料
从测试数据t;
产出:

产品|原材料|更新的|原材料 :------ | :----------- | :------------------- 一个|空|苹果 一个|空|苹果 一个|空|苹果 苹果 B |零|橙色 B |零|橙色 B |零|橙色 B |零|橙色 B|橙色|橙色 C |空|香蕉 C |空|香蕉 C |空|香蕉 C |空|香蕉 C |空|香蕉 C |香蕉|香蕉
dbfiddle

当您说您正在寻找一些“第一”值时,您的样本数据表明您只希望所有相同的产品具有相同的材质:

update mytable m1 set material = 
(
  select min(material)
  from mytable m2
  where m2.product = m1.product
);
如果您只想选择此数据。然后你可以使用这个:

select product, min(material) over (partition by product)
from mytable;
根据docs()的说法,obie似乎对分析窗口函数使用了一种特殊的语法(
,例如MIN()OVER()
):

您必须通过查看相应的
评估支持级别
来启用此功能


(我希望我没有弄错。否则,请阅读本文中的文档,然后自己尝试类似的方法。)

Oracle没有
IFNULL
功能。如果你在前两个选项中的一个上面交换了<代码> IFNUL/<代码> >代码> CueSeCs<代码>,你的代码会起作用。你认为“第一个”是哪一行?我在你的表达中看不到按顺序排列。每个产品可以有不同的材料吗?如果是这样,请在您的请求中添加这样一个例子。@MT0感谢您的帮助。我在OBIEE下使用他们的逻辑SQL,IFNULL是提供的函数之一。@ThorstenKettner感谢您的帮助。在这种情况下,我只看每个产品的一个组件。感谢联系GMB。我在OBIEE环境中尝试了这两个建议的代码,但都不起作用。我使用类似的设置测试了NVL()函数,但它也出现了错误。我猜想,Oracle中的逻辑SQL不理解NVL()。我还尝试了下面的代码,它也导致了错误。关于错误可能在哪里的想法?IFNULL(原材料,评估('LAG(%1,1)over(PARTITION BY%2)'AS varchar2(20),原材料,项目编号))感谢联系Bhanu Yadav。示例图表是我案例的简化版本,它有几十种产品,并且它们会定期更改。因此,在我的情况下,手动编码每个项目代码可能不适用。然而,我真的很感谢你的建议代码,这可能是一个解决未来的情况!Hi@JonathanChan,我只对工作代码使用硬编码值,这就是临时表。主代码在with子句下面,我使用first_值和partition by子句以及order by来区分值。在select a.*中,临时a的第一个产品(按产品订单按产品划分)上的第一个产品值(原材料忽略空值);谢谢你的澄清。虽然OBIEE计算的度量值无法运行此代码,但它定义了
update mytable m1 set material = 
(
  select min(material)
  from mytable m2
  where m2.product = m1.product
);
select product, min(material) over (partition by product)
from mytable;
select
  product,
  evaluate('min(%1) over (partition by %2)', material, product)
from mytable;