Search code examples
sqloracle-databaseplsqlnull

SQL extra null lines


I need my SQL query to return 15(fifteen) lines total. if it returns less than 15 rows, it needs to complete with null lines, if it returns more than 15 rows, it shows only the top 15. Can someone help me please?

select * from (select IDCODFATURA,  
       PAGINA, 
       TARIFA_RES_TE, 
       VALOR_ICMS_TE, 
       TARIFA_COM_ICMS_TE, 
       TARIFA_SEM_ICMS_TE, 
       VALOR_PISCOFINS_TE, 
       VALOR_COM_ICMS_TE, 
       VALOR_SEM_ICMS_TE, 
       VALOR_BASE_ICMS,
       TARIFA_TUSD,
       case 
            when nvl(param_com_tributos.tipo_imp_imposto_fat,0) = 0 then base_fatura_itens.valor_com_icms
                else base_fatura_itens.VALOR_SEM_PCICMS
         end as valor, 
       case 
            when nvl(param_com_tributos.tipo_imp_imposto_fat,0) = 0 then base_fatura_itens.tarifa_com_icms
                else base_fatura_itens.tarifa_res
         end as tarifa,
       TARIFA_TE,
       usuario,
       GUID,
       TIPO_DESCONTO_MICROGERACAO,
       (select VALOR_PIS 
          from base_fatura_web 
         where IDCODFATURA = :IDCODFATURA
           and PAGINA = :PAGINA
           and GUID = :GUID
           and usuario = :usuario) as VALOR_PIS,
       (select VALOR_COFINS 
          from base_fatura_web 
         where IDCODFATURA = :IDCODFATURA
           and PAGINA = :PAGINA
           and GUID = :GUID
           and usuario = :usuario) as VALOR_COFINS
      from base_fatura_itens,
           param_com_tributos
     where IDCODFATURA = :IDCODFATURA
       and PAGINA = :PAGINA
        and param_com_tributos.idparam=1 
        and base_fatura_itens.GUID = :GUID
        and base_fatura_itens.usuario = :usuario
        and base_fatura_itens.descricao <> 'ICMS Descontos tarifários'
      order by classificacao,sequencia)
      where rownum <=15

Solution

  • As mentioned in the comments, use a helper table that always gives you 15 rows. The example below is on the emp/dept sample data but you should be able to do this against your dataset as well. The emp table has 14 rows.

    step 1: generate 15 null rows

    select level
      from dual
    connect by
       level - 1< 15
    

    step 2: add a rownumber to your original query. This will be used to join to the helper table. Change the order by to whatever you need to satisfy your "top 15" condition.

    select ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY e.ename),  
           e.ename, 
           e.job 
      from emp e 
    

    Now put it all together:

    with dummy_rows (rn) as
    (
    select level
      from dual
    connect by
        level - 1< 15
    )
    ,
    my_emp_query(rn, ename, job) as
    (
    select ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY e.ename),  
           e.ename, 
           e.job 
      from emp e 
    )
    select d.rn, e.ename, e.job 
      from 
      dummy_rows d
      left outer join my_emp_query e on d.rn = e.rn    ;
    
            RN ENAME      JOB      
    ---------- ---------- ---------
             1 ADAMS      CLERK    
             2 ALLEN      SALESMAN 
             3 BLAKE      MANAGER  
             4 CLARK      MANAGER  
             5 FORD       ANALYST  
             6 JAMES      CLERK    
             7 JONES      MANAGER  
             8 KING       PRESIDENT
             9 MARTIN     SALESMAN 
            10 MILLER     CLERK    
            11 SCOTT      ANALYST  
            12 SMITH      CLERK    
            13 TURNER     SALESMAN 
            14 WARD       SALESMAN 
            15                     
    
    15 rows selected. 
    

    Note row 15 is empty since there is no matching record in the emp table. Change the 15 to 5 and you'll only get 5 rows.