DOUBT IN SQL -TURN ROWS INTO COLUMNS

Asked

Viewed 249 times

1

I got this one query, it brings to the same product 3 rows of result, wanted these results to be returned in columns, how to do?

SELECT CODPROD, EMB 
FROM TABELA
WHERE PRODUTO = 2

this research brings the following:

CODPROD | EMBALAGEM
      2 |       1X1
      2 |       1X2
      2 |       1X3

I wish you’d bring it like this:

      2 | 1X1 | 1X2 | 1X3
  • 1

    Try to explain better please

  • this search brings the following: CODPROD, PACKAGING 2 | 1X1 2 | 1X2 2 | 1X3

  • Man, I’m sorry, but I’m not getting it... Try to literally draw or give a clearer example than you need, put it as part of the question please

  • From what I understand, you need to return an array, example: Array[2]=> "1X1", "1X2", "1X3", in this way?

  • I believe that yes, that it returns in a row only the results of others in columns

3 answers

2

If the version of yours Oracle really is the 11g use the function LISTAGG:

SELECT CODPROD,
       LISTAGG(EMB, ', ') WITHIN GROUP (ORDER BY EMB) AS EMBALAGEM
  FROM TABELA
 WHERE PRODUTO = 2
 GROUP BY CODPROD

LISTAGG

For a specified Measure, LISTAGG Orders data Within each group specified in the ORDER BY clause and then concatenates the values of the Measure column.

In free translation:

For a specified column, the LISTAGG sorts the data within each group specified in the clause ORDER BY and concatenates the column values.

  • But then he concatenates everything into one field, wanted it to be in different fields, you know?

  • @Dynamically Marcosvinicius is very complicated to achieve

1

Use the function PIVOT to bring your rows in columns:

Example:

SELECT *
  FROM (SELECT 1 codigo, 'Carro' nome FROM dual UNION ALL 
        SELECT 2 codigo, 'Moto' nome FROM dual UNION ALL 
        SELECT 3 codigo, 'Avião' nome FROM dual )    
PIVOT
(
 MAX(codigo) FOR nome IN ('Carro' Carro,'Moto' Moto,'Avião' Avião)
)

Upshot:

Resultado query

see rotating on SQL Fiddle.

More information on the subject can be found here.

A more advanced option would be to create a function that runs the SQL dynamically and returns a CURSOR, when you don’t know the values that can return...

Follow an example:

CREATE OR REPLACE FUNCTION fun_linhas_para_tabelas RETURN SYS_REFCURSOR IS

  sqlqry CLOB;
  cols   CLOB;
  TYPE t_ref_cursor IS REF CURSOR;
  c t_ref_cursor;

BEGIN

  SELECT listagg('''' || nome || ''' as "' || nome || '"', ',') within GROUP(ORDER BY nome)
    INTO cols
    FROM (SELECT 1 codigo, 'Carro' nome
            FROM dual
          UNION ALL
          SELECT 2 codigo, 'Moto' nome
            FROM dual
          UNION ALL
          SELECT 3 codigo, 'Avião' nome
            FROM dual);

  sqlqry := 'select * from
             (
                SELECT 1 codigo, ''Carro'' nome FROM dual UNION ALL
                SELECT 2 codigo, ''Moto'' nome FROM dual UNION ALL
                SELECT 3 codigo, ''Avião'' nome FROM dual
             )
             pivot
             (
               Max(codigo) for nome in (' || cols || ')
             )';


  OPEN c FOR sqlqry;
  RETURN c;

END;
  • I used the anchor and got a question, when I do not know the results of the lines put what? select * from ( select PACKING as "PACKING", CODPROD from TAB_EMBALAGEM t WHERE CODPROD = 15250 ) pivot ( MAX(PACKING) for PACKING in ('1X12' as "EMB1",'1X6' "EMB2",'UNIT' "EMB3") )

  • I complemented it with another way of doing...

1

You need to use the PIVOT, it will turn rows into columns, for example:

Select CODPROD
         , [1] as coluna_um
         , [2] as coluna_dois
         , [3] as coluna_tres
from TABELA pivot (Embalagem for Emb ([1],[2],[3])) p
order by 1;

You will have to have 3 values, one for the first column, in case the CODPROD, other for the other columns in the case of EMB, and the other to bring the value of CODPROD x EMB, in the case I believe it is the PACKING.

  • I used the pivot and got a doubt, when I do not know the results of the lines put what? select * from (
 select EMBALAGEM as "EMBALAGEM", CODPROD
 from TAB_EMBALAGEM t WHERE CODPROD = 15250
)
pivot 
(
 MAX(EMBALAGEM)
 for EMBALAGEM in ('1X12' as "EMB1",'1X6' "EMB2",'UNIDADE' "EMB3")
)
order by 1

  • Usually you need to know the result of the columns, for example you want to bring the products x the sales per month, then you will map the months in columns (a year would be 12 columns), because what is the real sense of your analysis? What do you need to analyze by turning rows into columns? you will create some report?

  • If it is an excel report you don’t even need to turn the rows into columns, but rather create a dynamic table with this result and place the rows in columns, we need to know the final purpose.

  • It is a report that I need to create. I have more than 6,000 products, I have no way of knowing the result of each row to turn into column.

  • How will you create a report with 6000 columns? It is not easier to extract the database and treat the data with a dynamic in excel, or a power bi?

  • The report that I will create would have to show all the products and how many packages it has, so imagine there have to reference packaging by packaging in the pivot? There’s no way, there’s nothing more automatic?

  • The only way I know is you make your bi, like excel and power bi collect the query, or connect the query or the database view, and it make this automatic generation of columns. I’ve used pivot and unpivot a few times and always used fixed columns, it doesn’t make much sense you create infinite columns, mainly for the difficulty of the end user with reading the data.

  • I was able to create a view.

  • Share this information with us.

  • was like: CREATE OR REPLACE VIEW EMB_LINHA AS
SELECT codprod,
 embalagem || '-' || unidade AS emba,
 
 ROW_NUMBER () OVER (PARTITION BY codprod ORDER BY embalagem) AS linha
 FROM TABELA
 WHERE 1 = 1
 order by emba

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.