使用 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;
您可以简单地通过首先定义预期的行然后外部应用您的聚合。一个例子使用 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
这是另一种方法:
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;
我有资料,有简单的方法吗?
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;
您可以简单地通过首先定义预期的行然后外部应用您的聚合。一个例子使用 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
这是另一种方法:
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;