Concatenate columns into rows

Asked

Viewed 322 times

5

I’m trying to take several columns and turn them into a single row, but without success.

That’s the select I’m trying to make:

SELECT (`dias2produto`+`dias4produto`) as 'Até 4 dias', round((((`dias2produto`+`dias4produto`)*100)/`total_produto`),2) as percentual_4dias,
       (`dias7produto`) as 'De 5 à 7 dias', round(((`dias7produto`*100)/`total_produto`),2) as percentual_7dias,
       (`dias21produto`) as 'De 8 à 21 dias', round(((`dias21produto`*100)/`total_produto`),2) as percentual_21dias,
       (`dias28produto`) as 'De 22 à 28 dias', round(((`dias28produto`*100)/`total_produto`),2) as percentual_28dias,
       (`dias60produto`) as 'De 29 à 60 dias', round(((`dias60produto`*100)/`total_produto`),2) as percentual_60dias,
       (`dias_endproduto`) as 'Mais de 60 dias', round(((`dias_endproduto`*100)/`total_produto`),2) as percentual_m60dias,
       `total_produto`

I tried using group_concat, but it put everything in a single line and not in separate lines. I also tried to find out about Pivot, but I didn’t understand how to use.

The expected result is this one:

inserir a descrição da imagem aqui


I appreciate your attention, but I managed to solve my problem using another way:

SELECT
    CASE    WHEN FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) > 0  AND FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) <= 2 THEN 'Até 4 dias'
            WHEN FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) > 2 AND FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) <= 4 THEN 'Até 4 dias'    
            WHEN FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) > 4 AND FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) <= 7 THEN 'De 5 à 7 dias' 
            WHEN FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) > 7 AND FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) <= 21 THEN 'De 8 à 21 dias'  
            WHEN FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) > 21 AND FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) <= 28 THEN 'De 22 à 28 dias' 
            WHEN FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) > 28 AND FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) <= 60 THEN 'De 29 à 60 dias'     
            WHEN FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) > 60 AND FN_DIFF_DAYS( DATE( t.created ), DATE( f.vencimento )) <= 1000000 THEN 'Mais de 60 dias'
            ELSE 0 END AS `Prazo` ,      
    sum(( f.product_adults + f.product_children + f.product_baby )) AS `Quantidade Geral de Produto`,
    sum(tpf.qt_produto) as qt_produto

I was able to take a little bit of every hint here and formulate my result.

  • 1

    Can you put the table structure in http://sqlfiddle.com/ ? If you can put data as well, it would be even better.

  • 1

    Is missing the SUM( formula ) to group in a single row. SELECT SUM( dias2produto + dias4produto) AS 'Ate 4 dias' ... and the same for the rest. Search for "aggregation functions" - SUM, AVG, MAX, MIN, etc

  • 1

    You’d like to concatenate the data from multiple columns and display in a single row, that’s it?

1 answer

9


If you want line by line, the way is union

SELECT SUM(`dias2produto`+`dias4produto`) AS 'Até 4 dias',
       SUM(ROUND((((`dias2produto`+`dias4produto`)*100)/`total_produto`),2)) as p4d
UNION
SELECT SUM(`dias7produto`) as 'De 5 à 7 dias',
       SUM(ROUND(((`dias7produto`*100)/`total_produto`),2) as percentual_7dias
UNION
-- faça novo SELECT para cada linha, com um UNION entre eles --

To take the totals of each select, not line by line, we use the SUM, which is an aggregation function.

  • SUM to sum all lines

  • AVG to find the average

  • MAX to get the highest value

  • MIN to get the smallest

There are other:

https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html

In your case:

SELECT SUM(`dias2produto`+`dias4produto`) as 'Até 4 dias',
       SUM(ROUND(((dias2produto+dias4produto)*100)/SUM(`total_produto`),2)) as perc_4dias,
       SUM(`dias7produto`) as 'De 5 à 7 dias',
       -- faça isso em todos os casos, note o SUM aqui no total ^tambem ^^^^

You can write in more ways than one:

round(((SUM(dias2produto)+SUM(dias4produto)*100)/SUM(`total_produto`),2) as perc_4dias,
      --^^^               ^^^                    ^^^ agrupando campos
round(((SUM(dias2produto+dias4produto)*100)/SUM(`total_produto`),2) as perc_4dias,
      --^^^                                 ^^^ agrupando partes
SUM(round((((dias2produto+dias4produto)*100)/`total_produto`,2)) as perc_4dias,
--^ agrupando tudo


If you need to, you can control the aggregation with the GROUP BY. You can unite the two like this:

SELECT SUM( salario ) GROUP BY YEAR( data )

In this case it will have the totals but separated one row per year instead of one line only.

Browser other questions tagged

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