How to add different totals by columns in MySQL?

1

Good morning

I have the following table in MySQL :

id     |    pais    |  categoria
193    |     BR     |     A
188    |     BR     |     A
133    |     BR     |     B
145    |     BR     |     C
124    |     CA     |     A
165    |     CA     |     B
113    |     CA     |     B
177    |     CA     |     C
197    |     MX     |     A
213    |     MX     |     B
208    |     MX     |     C
222    |     MX     |     C

I want to get the category total for each country in a different column, that is:

categoria  |  totalBR  |  totalCA  |  totalMX
    A      |    2      |    1      |    1
    B      |    1      |    2      |    1
    C      |    1      |    1      |    2

It occurs to me to create a temporary table for the total by country and category but I think it would not be such a good idea since I would have to create 9 temporary tables and then make them a union all

UPDATE

The 1st table I get from a query SQL and since I could not get the total of different columns of the 1st table, modify my query SQL getting the following table:

  |      id     |    pais    |  categoriaBR  | categoriaCA  | categoriaMX  |
  |      193    |     BR     |     A         |     null     |    null      |
  |      188    |     BR     |     A         |     null     |    null      |
  |      133    |     BR     |     B         |     null     |    null      |
  |      145    |     BR     |     C         |     null     |    null      |
  |      124    |     CA     |    null       |       A      |    null      |
  |      165    |     CA     |    null       |       B      |    null      |
  |      113    |     CA     |    null       |       B      |    null      |
  |      177    |     CA     |    null       |       C      |    null      |
  |      197    |     MX     |    null       |     null     |      A       |
  |      213    |     MX     |    null       |     null     |      B       |
  |      208    |     MX     |    null       |     null     |      C       |
  |      222    |     MX     |    null       |     null     |      C       |

and create 9 temporary tables

#------------------------------------------------categoriasBR------------------------------------------------
DROP temporary table IF EXISTS categoriaBR1;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaBR1 AS ( 
    SELECT 1 as id, ifnull(sum(case when categoriaBR = 'A' then 1 else 0 end),0) as 'Total'
        FROM tabla
);

DROP temporary table IF EXISTS categoriaBR2;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaBR2 AS ( 
    SELECT 2 as id, ifnull(sum(case when categoriaBR = 'B' then 1 else 0 end),0) as 'Total'
        FROM tabla
);

DROP temporary table IF EXISTS categoriaBR3;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaBR3 AS ( 
    SELECT 3 as id, ifnull(sum(case when categoriaBR = 'C' then 1 else 0 end),0) as 'Total'
        FROM tabla
);

#------------------------------------------------categoriasCA------------------------------------------------
    DROP temporary table IF EXISTS categoriaCA4;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaCA4 AS ( 
    SELECT 1 as id, ifnull(sum(case when categoriaCA = 'A' then 1 else 0 end),0) as 'Total'
        FROM tabla
);

DROP temporary table IF EXISTS categoriaCA5;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaCA5 AS ( 
    SELECT 2 as id, ifnull(sum(case when categoriaCA = 'B' then 1 else 0 end),0) as 'Total'
        FROM tabla
);

DROP temporary table IF EXISTS categoriaCA6;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaCA6 AS ( 
    SELECT 3 as id, ifnull(sum(case when categoriaCA = 'C' then 1 else 0 end),0) as 'Total'
        FROM tabla
);

#---------------------------------------------------categoriasMX--------------------------------------------------
DROP temporary table IF EXISTS categoriaMX7;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaMX7 AS ( 
    SELECT 1 as id, ifnull(sum(case when categoriaMX = 'A' then 1 else 0 end),0) as 'Total'
        FROM tabla
);

DROP temporary table IF EXISTS categoriaMX8;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaMX8 AS ( 
    SELECT 2 as id, ifnull(sum(case when categoriaMX = 'B' then 1 else 0 end),0) as 'Total'
        FROM tabla
);

DROP temporary table IF EXISTS categoriaMX9;
CREATE TEMPORARY TABLE IF NOT EXISTS categoriaMX9 AS ( 
    SELECT 3 as id, ifnull(sum(case when categoriaMX = 'C' then 1 else 0 end),0) as 'Total'
        FROM tabla
);
#------------------------------------UNION DE TODO---------------------------------------------------------------    
select 'A' as Categoria, categoriaBR1.Total as TotalBR, categoriaCA1.Total as TotalCA, categoriaMX1.Total as TotalMX from categoriaBR1
        INNER JOIN categoriaCA1 ON categoriaBR1.id = categoriaCA1.id
        INNER JOIN categoriaMX1 ON categoriaBR1.id = categoriaMX1.id
    union all
select 'B' as Categoria, categoriaBR2.Total as TotalBR, categoriaCA2.Total as TotalCA, categoriaMX2.Total as TotalMX from categoriaBR2
        INNER JOIN categoriaCA2 ON categoriaBR2.id = categoriaCA2.id
        INNER JOIN categoriaMX2 ON categoriaBR2.id = categoriaMX2.id
    union all
select 'C' as Categoria, categoriaBR3.Total as TotalBR, categoriaCA3.Total as TotalCA, categoriaMX3.Total as TotalMX from categoriaBR3
        INNER JOIN categoriaCA3 ON categoriaBR3.id = categoriaCA3.id
        INNER JOIN categoriaMX3 ON categoriaBR3.id = categoriaMX3.id

It is worth mentioning that with the creation of the 9 temporary tables I get the result I want but the idea I have is to reach the same result without so much temporary table.

    
asked by El Cóndor 21.02.2018 в 04:53
source

1 answer

3

You need to treat the data as if it were a pivot type table. It is done as follows:

SELECT
  category,
  COUNT(CASE WHEN country = 'BR' THEN 1 ELSE NULL END) AS 'BR',
  COUNT(CASE WHEN country = 'CA' THEN 1 ELSE NULL END) AS 'CA',
  COUNT(CASE WHEN country = 'MX' THEN 1 ELSE NULL END) AS 'MX'
FROM foo
GROUP BY category
ORDER BY category;

I'll leave you the example working here on sqlfiddle .

    
answered by 21.02.2018 / 09:10
source