我的表名为user_plan_dtl,其中包含userid,plan description和contact date列。我想根据计划描述每个月的用户数量。并且应该仅在给定的日期范围内选择月份。 我在mysql中有数据库。
下面是表user_plan_dtl
userid contactdate plandesc
USR001 March ICMA
USR003 March ICMA
USR004 April FTDA
USR005 April FTDA
USR006 April FTDA
USR007 April ICMA
USR008 April ICMA
USR009 May FTDA
USR002 May FTDA
USR001 May ICMA
我希望输出如下:
Count March April May
Total 2 5 3
FTDA 0 3 2
ICMA 2 2 1
我已尝试使用以下查询,但我将获得所有月份的输出。
select d.Plandesc as AssignedUsers, max(d.January) as January,max(d.February) as February,max(d.March) as March,
max(d.April) as April ,max(d.May)as May,max(d.June)as June,
max(d.July) as July,max(d.August)as August,max(d.September) as September,
max(d.October)as October,max(d.November) as November ,max(d.December)as December from
(Select Plandesc,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='January' THEN userid END )) AS January,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='February' THEN userid END )) AS February,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='March' THEN userid END )) AS March,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='April' THEN userid END )) AS April,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='May' THEN userid END )) AS May,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='June' THEN userid END )) AS June,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='July' THEN userid END )) AS July,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='August' THEN userid END )) AS August,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='September' THEN userid END )) AS September,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='October' THEN userid END )) AS October,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='November' THEN userid END )) AS November,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='December' THEN userid END )) AS December
from user_plan_dtl
where Plandesc in ('FTDA','ICMA')
and DATE_FORMAT(contactdate, '%Y-%m-%d') >= '2017-01-01' and DATE_FORMAT(contactdate, '%Y-%m-%d') <= '2017-07-05'
group by MONTHNAME(contactdate),Plandesc
union all
Select 'Total' as Plandesc,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='January' THEN userid END )) AS January,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='February' THEN userid END )) AS February,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='March' THEN userid END )) AS March,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='April' THEN userid END )) AS April,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='May' THEN userid END )) AS May,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='June' THEN userid END )) AS June,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='July' THEN userid END )) AS July,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='August' THEN userid END )) AS August,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='September' THEN userid END )) AS September,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='October' THEN userid END )) AS October,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='November' THEN userid END )) AS November,
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)='December' THEN userid END )) AS December
from user_plan_dtl
where Plandesc in ('FTDA','ICMA')
and DATE_FORMAT(contactdate, '%Y-%m-%d') >= '2017-01-01' and DATE_FORMAT(contactdate, '%Y-%m-%d') <= '2017-07-05'
group by MONTHNAME(contactdate)
) as d group by d.Plandesc order by case when d.Plandesc = 'Total' then 0 else 1 end,d.Plandesc
任何人都可以为我提供解决方案吗?提前谢谢。
答案 0 :(得分:2)
使用CONCAT
和GROUP_CONCAT
构建复杂查询。
set @sql=NULL;
select group_concat(distinct concat(
' COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)="',c_month,
'" THEN userid END )) AS "',c_month,'"') separator ',')
from (select distinct contactdate as c_month from user_plan_dtl) t into @sql;
select @sql;
(请注意,我已将您在此处发布的数据中的contactdate
用作一个月,而不是日期)
这将在变量@sql
中为您提供一个字符串:
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)="March" THEN userid END ))
AS "March",
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)="April" THEN userid END ))
AS "April",
COUNT(DISTINCT(CASE WHEN MONTHNAME(contactdate)="May" THEN userid END ))
AS "May"
然后你可以操纵这个字符串
set @sql=concat('SELECT ',@sql);
select @sql;
等等。 (提示:为整个语句创建另一个变量,并将其与@sql
连接起来)。最后,您必须准备并执行此sql语句:
PREPARE stmnt from @sql;
EXECUTE stmnt;
DEALLOCATE stmnt;
答案 1 :(得分:1)
我想出了这个解决方案,设置变量并使用预处理语句:
DROP TABLE IF EXISTS user_plan_temp;
SET @JanTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='January' );
SET @FebTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='February');
SET @MarTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='March');
SET @AprTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='April');
SET @MayTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='May');
SET @JunTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='June');
SET @JulTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='July');
SET @AugTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='August');
SET @SepTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='September');
SET @OctTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='October');
SET @NovTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='November');
SET @DecTotal = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc IN ('FTDA','ICMA') AND MONTHNAME(contactdate)='December');
SET @SQLq = 'CREATE TEMPORARY TABLE user_plan_temp AS (SELECT "Total" AS Count ';
SET @SQLq = CONCAT(@SQLq, IF(@JanTotal > 0, ', @JanTotal AS January',''));
SET @SQLq = CONCAT(@SQLq, IF(@FebTotal > 0, ', @FebTotal AS February',''));
SET @SQLq = CONCAT(@SQLq, IF(@MarTotal > 0, ', @MarTotal AS March',''));
SET @SQLq = CONCAT(@SQLq, IF(@AprTotal > 0, ', @AprTotal AS April',''));
SET @SQLq = CONCAT(@SQLq, IF(@MayTotal > 0, ', @MayTotal AS May',''));
SET @SQLq = CONCAT(@SQLq, IF(@JunTotal > 0, ', @JunTotal AS June',''));
SET @SQLq = CONCAT(@SQLq, IF(@JulTotal > 0, ', @JulTotal AS July',''));
SET @SQLq = CONCAT(@SQLq, IF(@AugTotal > 0, ', @AugTotal AS August',''));
SET @SQLq = CONCAT(@SQLq, IF(@SepTotal > 0, ', @SepTotal AS September',''));
SET @SQLq = CONCAT(@SQLq, IF(@OctTotal > 0, ', @OctTotal AS October',''));
SET @SQLq = CONCAT(@SQLq, IF(@NovTotal > 0, ', @NovTotal AS November',''));
SET @SQLq = CONCAT(@SQLq, IF(@DecTotal > 0, ', @DecTotal AS December',''));
SET @SQLq = CONCAT(@SQLq, ')');
PREPARE stmt1 FROM @SQLq;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
-- SELECT * FROM user_plan_temp;
SET @SQLq2 = 'INSERT INTO user_plan_temp VALUES("FTDA" ';
SET @JanFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='January' );
SET @SQLq2 = CONCAT(@SQLq2, IF(@JanTotal > 0, ', @JanFTDA',''));
SET @FebFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='February');
SET @SQLq2 = CONCAT(@SQLq2, IF(@FebTotal > 0, ', @FebFTDA',''));
SET @MarFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='March');
SET @SQLq2 = CONCAT(@SQLq2, IF(@MarTotal > 0, ', @MarFTDA',''));
SET @AprFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='April');
SET @SQLq2 = CONCAT(@SQLq2, IF(@AprTotal > 0, ', @AprFTDA',''));
SET @MayFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='May');
SET @SQLq2 = CONCAT(@SQLq2, IF(@MayTotal > 0, ', @MayFTDA',''));
SET @JunFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='June');
SET @SQLq2 = CONCAT(@SQLq2, IF(@JunTotal > 0, ', @JunFTDA',''));
SET @JulFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='July');
SET @SQLq2 = CONCAT(@SQLq2, IF(@JulTotal > 0, ', @JulFTDA',''));
SET @AugFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='August');
SET @SQLq2 = CONCAT(@SQLq2, IF(@AugTotal > 0, ', @AugFTDA',''));
SET @SepFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='September');
SET @SQLq2 = CONCAT(@SQLq2, IF(@SepTotal > 0, ', @SepFTDA',''));
SET @OctFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='October');
SET @SQLq2 = CONCAT(@SQLq2, IF(@OctTotal > 0, ', @OctFTDA',''));
SET @NovFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='November');
SET @SQLq2 = CONCAT(@SQLq2, IF(@NovTotal > 0, ', @NovFTDA',''));
SET @DecFTDA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'FTDA' AND MONTHNAME(contactdate)='December');
SET @SQLq2 = CONCAT(@SQLq2, IF(@DecTotal > 0, ', @DecFTDA',''));
SET @SQLq2 = CONCAT(@SQLq2, ')');
-- SELECT @SQLq2;
PREPARE stmt2 FROM @SQLq2;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
SET @SQLq3 = 'INSERT INTO user_plan_temp VALUES("FTDA" ';
SET @JanICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='January' );
SET @SQLq3 = CONCAT(@SQLq3, IF(@JanTotal > 0, ', @JanICMA',''));
SET @FebICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='February');
SET @SQLq3 = CONCAT(@SQLq3, IF(@FebTotal > 0, ', @FebICMA',''));
SET @MarICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='March');
SET @SQLq3 = CONCAT(@SQLq3, IF(@MarTotal > 0, ', @MarICMA',''));
SET @AprICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='April');
SET @SQLq3 = CONCAT(@SQLq3, IF(@AprTotal > 0, ', @AprICMA',''));
SET @MayICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='May');
SET @SQLq3 = CONCAT(@SQLq3, IF(@MayTotal > 0, ', @MayICMA',''));
SET @JunICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='June');
SET @SQLq3 = CONCAT(@SQLq3, IF(@JunTotal > 0, ', @JunICMA',''));
SET @JulICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='July');
SET @SQLq3 = CONCAT(@SQLq3, IF(@JulTotal > 0, ', @JulICMA',''));
SET @AugICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='August');
SET @SQLq3 = CONCAT(@SQLq3, IF(@AugTotal > 0, ', @AugICMA',''));
SET @SepICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='September');
SET @SQLq3 = CONCAT(@SQLq3, IF(@SepTotal > 0, ', @SepICMA',''));
SET @OctICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='October');
SET @SQLq3 = CONCAT(@SQLq3, IF(@OctTotal > 0, ', @OctICMA',''));
SET @NovICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='November');
SET @SQLq3 = CONCAT(@SQLq3, IF(@NovTotal > 0, ', @NovICMA',''));
SET @DecICMA = (Select COUNT(DISTINCT(userid)) from user_plan_dtl WHERE plandesc = 'ICMA' AND MONTHNAME(contactdate)='December');
SET @SQLq3 = CONCAT(@SQLq3, IF(@DecTotal > 0, ', @DecICMA',''));
SET @SQLq3 = CONCAT(@SQLq3, ')');
PREPARE stmt3 FROM @SQLq3;
EXECUTE stmt3;
DEALLOCATE PREPARE stmt3;
SELECT * FROM user_plan_temp;