Search code examples
sqlnullobiee

Oracle - Fill null values in a column with values from another column


I am using Oracle 11.1.1.9.0 and my goal is to fill the Null values with the first NOT NULL values in "Raw Materials" column by each product i.e A, B and C in Product column. An example table and the intended result are illustrated at the end of this request.

None of the code sets in below works: 


CODE 1:

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

CODE 2:

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

CODE 3:

COALESCE(lag(Raw Materials ignore null) OVER (partition by Product), 
         Raw Materials)

CODE 4:

IFNULL(Raw Materials, EVALUATE('LAG(%1, 1) OVER (PARTITION BY %2)' AS varchar2(20), Raw Materials, Product))

Note: IFNULL function does work in the environment. It was tested with IFNULL(Raw Materials, '1') and it resulted in all null values becoming 1 in Raw Materials column.

Thank you.

+---------+----------+      +---------+----------+  
| 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.

The below link "Oracle code environment" shows the code environment and samples of Oracle Logical SQL function. Oracle code environment

Oracle Logical SQL manual: https://docs.oracle.com/middleware/11119/biee/BIEUG/appsql.htm#CHDDCFJI


Solution

  • While you say that you are looking for some "first" value, your sample data suggests that you just want all same products to have the same material:

    update mytable m1 set material = 
    (
      select min(material)
      from mytable m2
      where m2.product = m1.product
    );
    

    If you just want to select this data. Then you can use this:

    select product, min(material) over (partition by product)
    from mytable;
    

    According to the docs (https://docs.oracle.com/cd/E28280_01/bi.1111/e10540/sqlref.htm#BIEMG678) it seems OBIEE uses a special syntax for analytic window functions (e.g. MIN() OVER()):

    select
      product,
      evaluate('min(%1) over (partition by %2)', material, product)
    from mytable;
    

    You must enable this by seeting the EVALUATE_SUPPORT_LEVEL accordingly.

    (I hope I got this right. Otherwise read the docs on this and try something along the lines for yourself.)