Question

i have a denormalized table, where i have to count the number of same values in other columns. I'm using the InfiniDB Mysql Storage Engine.

This is my Table:

col1 | col2 | col3
------------------
A    | B    | B
A    | B    | C
A    | A    | A

This is what i expect:

col1Values | col2Values | col3Values
------------------------------------
    1      |     2      |      2     -- Because B is in Col2 and Col3
    1      |     1      |      1     
    3      |     3      |      3

Is there something like

-- function count_values(needle, haystack1, ...haystackN)
select count_values(col1, col1, col2, col3) as col1values -- col1 is needle
    , count_values(col2, col1, col2, col3) as col2values -- col2 is needle
    , count_values(col3, col1, col2, col3) as col3values -- col3 is needle
from table

or am i missing something simple that will do the trick? :-)

Thanks in advance

Roman

Was it helpful?

Solution 3

I have found a different, very very simple solution :-)

select if(col1=col1,1,0) + if(col2=col1,1,0) + if(col3=col1,1,0) as col1values -- col1 is needle
from table

OTHER TIPS

     select 
        CASE WHEN col1 = col2 and col1=col3 THEN '3' 
             WHEN col1 = col2 or col1=col3 THEN '2' 
             WHEN col1 != col2 and col1!=col3 THEN '1' 
        ELSE '0' END AS col1_values, 

        CASE WHEN col2 = col1 and col2=col3 THEN '3' 
             WHEN col2 = col1 or col2=col3 THEN '2' 
             WHEN col2 != col1 and col2!=col3 THEN '1' 
        ELSE '0' END AS col2_values,

       CASE WHEN col3 = col1 and col3=col2 THEN '3' 
            WHEN col3 = col1 or col3=col2 THEN '2' 
            WHEN col3 != col1 and col3!=col2 THEN '1' 
       ELSE '0' END AS col3_values

FROM table_name

fiddle demo

Assuming the table has got a key, you could:

  1. Unpivot the table.

  2. Join the unpivoted dataset back to the original.

  3. For every column in the original, count matches against the unpivoted column.

Here's how the above could be implemented:

SELECT
  COUNT(t.col1 = s.col OR NULL) AS col1Values,
  COUNT(t.col2 = s.col OR NULL) AS col2Values,
  COUNT(t.col3 = s.col OR NULL) AS col3Values
FROM atable t
  INNER JOIN (
    SELECT
      t.id,
      CASE colind
        WHEN 1 THEN t.col1
        WHEN 2 THEN t.col2
        WHEN 3 THEN t.col3
      END AS col
    FROM atable t
    CROSS JOIN (SELECT 1 AS colind UNION ALL SELECT 2 UNION ALL SELECT 3) x
  ) s ON t.id = s.id
GROUP BY t.id
;

The subquery uses a cross join to unpivot the table. The id column is a key column. The OR NULL bit is explained in this answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top