使用 sql 计算 Mysql 中的多列是和否

Use sql count multiple columns yes and no in Mysql

我有资料,有简单的方法吗?

create table tb_count(
    id int not null auto_increment,
    col1 enum('yes', 'no'),
    col2 enum('yes', 'no'),
    col3 enum('yes', 'no'),
    col4 enum('yes', 'no'),
    primary key(id)
) default charset=utf8;

insert into tb_count values (null, 'yes', 'yes', 'no', 'yes');
insert into tb_count values (null, 'no', 'yes', 'no', 'no');
insert into tb_count values (null, 'no', 'yes', 'no', 'yes');
insert into tb_count values (null, 'no', 'no', 'no', 'no');

select * from tb_count;

enter image description here

# I want to get the following output:
# value col1  col2  col3  col4
# yes    1      3    0      2
# no     3      1    4      2

对了,我有更复杂的方法,我不想用union all

我的代码


SELECT
    'yes' AS 'value',
    SUM( CASE WHEN col1 = 'yes' THEN 1 ELSE 0 END ) AS col1,
    SUM( CASE WHEN col2 = 'yes' THEN 1 ELSE 0 END ) AS col2,
    SUM( CASE WHEN col3 = 'yes' THEN 1 ELSE 0 END ) AS col3,
    SUM( CASE WHEN col4 = 'yes' THEN 1 ELSE 0 END ) AS col4 
FROM
    tb_count
    UNION ALL
SELECT
    'no' AS 'value',
    SUM( CASE WHEN col1 = 'no' THEN 1 ELSE 0 END ) AS col1,
    SUM( CASE WHEN col2 = 'no' THEN 1 ELSE 0 END ) AS col2,
    SUM( CASE WHEN col3 = 'no' THEN 1 ELSE 0 END ) AS col3,
    SUM( CASE WHEN col4 = 'no' THEN 1 ELSE 0 END ) AS col4 
FROM
    tb_count

我想知道这样做是否是个好习惯,最好的方法是什么?

您可以通过一个查询来完成:

select yesno.yn, 
  sum(if(yesno.yn=c.col1, 1, 0)) as col1,
  sum(if(yesno.yn=c.col2, 1, 0)) as col2,
  sum(if(yesno.yn=c.col3, 1, 0)) as col3,
  sum(if(yesno.yn=c.col4, 1, 0)) as col3
from tb_count c
  join (
    select 'yes' yn
    union
    select 'no'
  ) as yesno
group by yesno.yn;

SQLFiddle

您可以简单地通过首先定义预期的行然后外部应用您的聚合。一个例子使用 CTE 来简化:

with v as (
    select 'yes' Value union all select 'no'
)
select value,
    Sum(case when col1=value then 1 else 0 end) col1,
    Sum(case when col2=value then 1 else 0 end) col2,
    Sum(case when col3=value then 1 else 0 end) col3,
    Sum(case when col4=value then 1 else 0 end) col4
from v cross join tb_count
group by value
  SELECT value,
         SUM(col1) AS col1,
         SUM(col2) AS col2,
         SUM(col3) AS col3,
         SUM(col4) AS col4
    FROM (
           SELECT col1 AS value, COUNT(col1) AS col1, 0 AS col2, 0 AS col3, 0 AS col4 FROM tb_count GROUP BY col1
           UNION SELECT col2 AS value, 0, COUNT(col2), 0, 0 FROM tb_count GROUP BY col2
           UNION SELECT col3 AS value, 0, 0, COUNT(col3), 0 FROM tb_count GROUP BY col3
           UNION SELECT col4 AS value, 0, 0, 0, COUNT(col4) FROM tb_count GROUP BY col4
         ) AS T
GROUP BY value
ORDER BY value DESC

你的方法很好,但可能会像这样缩短

SELECT 'yes' AS value,
       SUM( col1 = 'yes' ) AS col1,
       SUM( col2 = 'yes' ) AS col2,
       SUM( col3 = 'yes' ) AS col3,
       SUM( col4 = 'yes' ) AS col4 
 FROM tb_count
UNION ALL
SELECT 'no',
       SUM( col1 = 'no' ),
       SUM( col2 = 'no' ),
       SUM( col3 = 'no' ),
       SUM( col4 = 'no' )
 FROM tb_count
ORDER BY value DESC

为第二个查询

删除多余的CASE..WHEN表达式和别名

对于MySQL 8.0,它甚至会更短:

WITH t(value) AS
(
 SELECT 'yes' UNION ALL
 SELECT 'no'
)
SELECT value,
       SUM( col1 = value ) AS col1,
       SUM( col2 = value ) AS col2,
       SUM( col3 = value ) AS col3,
       SUM( col4 = value ) AS col4 
 FROM tb_count,
      t
GROUP BY value
ORDER BY value DESC

Demo

这是另一种方法:

SELECT 
  IF(y.yn=1,'yes','no')
, SUM(y.yn = col1) AS col1
, SUM(y.yn = col2) AS col2
, SUM(y.yn = col3) AS col3
, SUM(y.yn = col4) AS col4
FROM `tb_count` AS t
JOIN (SELECT 1 AS yn UNION ALL SELECT 2)  AS y
GROUP BY y.yn;