简体   繁体   English

MySQL查询以在Chartjs中显示数据

[英]MySql query to display data in Chartjs

I have users table with a flag of free user or paid users and with date of registration. 我的用户表带有免费用户或付费用户的标志,并带有注册日期。 Something like 就像是

+------------+-----------+--------------+
| USERNAME   | FREE_USER | DATE_OF_REG  |
+------------+-----------+--------------+
| user_name1 | y         | 2018-01-14   |
| user_name2 | n         | 2017-12-23   |
| user_name3 | y         | 2017-12-12   |
| user_name4 | y         | 2017-11-19   |
| user_name5 | n         | 2017-09-13   |
| user_name6 | y         | 2017-08-27   |
| user_name7 | n         | 2017-07-06   |
+------------+-----------+--------------+

I need count of free_users and paid_users for last 6 months and if there is no users registered in a month it should give 0 as free and paid count. 我需要最近6个月的free_users和paid_users计数,如果一个月内没有注册用户,则应将0设为免费和付费计数。

I want to create line chart for both free user and paid users as like in this example ( http://www.chartjs.org/samples/latest/charts/line/basic.html ). 我想为免费用户和付费用户创建折线图,如本例所示( http://www.chartjs.org/samples/latest/charts/line/basic.html )。 For this I need data in comma (,) separated format like: 为此,我需要使用逗号(,)分隔格式的数据,例如:

month_of_registration : ['August', 'September', 'October', 'November', 'December', 'January'] month_of_registration:['八月','九月','十月','十一月','十二月','一月']

free_users_count_for_related_month : [0, 1, 0, 1, 0, 1, 1] free_users_count_for_related_month:[0,1,0,1,0,1,1]

paid_users_count_for_related_month : [1, 0, 1, 0, 0, 1, 0] paid_users_count_for_related_month:[1、0、1、0、0、1、0]

How can I achieve this with mysql query in PHP. 如何在PHP中使用mysql查询来实现这一点。

I have written this query: 我写了这个查询:

SELECT MONTH(date_of_reg) as monthno, MONTHNAME(date_of_reg) as month_name, YEAR(date_of_reg) as year,
COUNT(CASE WHEN `free_user` = 'y' THEN 1 END) AS free_user,
COUNT(CASE WHEN `free_user` = 'n' THEN 1 END) AS paid, 
COUNT(CASE WHEN `free_user` != '' THEN 1 END) as total_users
FROM tbl_agents GROUP BY MONTH( date_of_reg ) ORDER BY year, monthno

But I didn't achieve which I want. 但是我没有达到我想要的。

You need to generate 6 rows for the months because there may be gaps in the registrations, and you would need to decide when this starts from, I have used the current date below as that point but it could be any wanted date. 您需要在每个月中生成6行,因为注册中可能会有空白,并且您需要确定何时开始,我使用了下面的当前日期作为起点,但是它可以是任何想要的日期。 Note I have worked backwards from that date. 请注意,我从该日期开始进行了倒退。

This subquery seeds the dates with the beginning of the current month, and the first day of the next month: 此子查询以当前月份的开始和下个月的第一天为日期播种日期:

set @datum := DATE_FORMAT(current_date, '%Y-%m-01');
...
cross join (select @datum dt_fm, @datum + interval 1 month dt_to) d

Then when joined to 6 rows of numbers (0 to 5) we calculate date ranges over the last 6 months, and they in turn allow us to place to the registrations into those monthly buckets for counting. 然后,当连接到6行数字(0到5)时,我们可以计算过去6个月的日期范围,它们又使我们可以将注册内容放入这些每月的存储桶中进行计数。

set @datum := DATE_FORMAT(current_date, '%Y-%m-01');

select
       monthname(dt_fm - interval n.n month) mnth
     , dt_fm - interval n.n month dt_fm
     , dt_to - interval n.n month dt_to
     , count(case when t.free_user = 'y' then 1 end) free_users
     , count(case when t.free_user = 'n' then 1 end) paid_users
from (
    select 0 n union all
    select 1 n union all
    select 2 n union all
    select 3 n union all
    select 4 n union all
    select 5 n
    ) n
cross join (select @datum dt_fm, @datum + interval 1 month dt_to) d
left join tbl_agents t on t.DATE_OF_REG >= dt_fm - interval n.n month
                      and t.DATE_OF_REG <  dt_to - interval n.n month
group by
       monthname(dt_fm - interval n.n month)
     , dt_fm - interval n.n month
     , dt_to - interval n.n month
order by dt_fm
;

Results: 结果:

|      mnth |      dt_fm |      dt_to | free_users | paid_users |
|-----------|------------|------------|------------|------------|
|    August | 2017-08-01 | 2017-09-01 |          1 |          0 |
| September | 2017-09-01 | 2017-10-01 |          0 |          1 |
|   October | 2017-10-01 | 2017-11-01 |          0 |          0 |
|  November | 2017-11-01 | 2017-12-01 |          1 |          0 |
|  December | 2017-12-01 | 2018-01-01 |          1 |          1 |
|   January | 2018-01-01 | 2018-02-01 |          1 |          0 |

Note that the count() function ignores null so the case expressions do not use an else so when the expression isn't met null is evaluaed and the count does not increment. 请注意, count()函数将忽略null因此case表达式不使用else因此当不满足表达式时将评估为null ,并且计数不会增加。 Alternatively you could use else null in the case expressions. 或者,您可以在case表达式中使用else null

I am going to assume that once you get that sql result in an array you can then work that into the inputs for your chart. 我将假设,一旦您将sql结果放入数组中,便可以将其应用于图表的输入中。

Demo at sqlfiddle sqlfiddle上的演示

SQL SQL

First up, you need to create a table (temporary or otherwise) which represents the last 6 months (tbl_agents may not have any records in it). 首先,您需要创建一个表(临时表或其他表),该表代表最近6个月(tbl_agents中可能没有任何记录)。 You can do this using the "union" syntax and the date_sub function (this makes it easy to follow what is happening): 您可以使用“联合”语法和date_sub函数来执行此操作(这使跟踪事件变得容易):

 select now() as month union 
 select date_sub(now(), INTERVAL 1 MONTH) as month union 
 select date_sub(now(), INTERVAL 2 MONTH) as month union 
 select date_sub(now(), INTERVAL 3 MONTH) as month union 
 select date_sub(now(), INTERVAL 4 MONTH) as month union 
 select date_sub(now(), INTERVAL 5 MONTH) as month union 
 select date_sub(now(), INTERVAL 6 MONTH) as month 

Output: 输出:

month 
2018-01-25T03:04:22Z 
2017-12-25T03:04:22Z 
2017-11-25T03:04:22Z
2017-10-25T03:04:22Z 
2017-09-25T03:04:22Z 
2017-08-25T03:04:22Z
2017-07-25T03:04:22Z

We can then use a LEFT JOIN to tbl_agents on the month and use your existing SQL to achieve the necessary output. 然后,我们可以在当月对tbl_agents使用LEFT JOIN并使用您现有的SQL来实现必要的输出。 Note, we're working from our temporary table above to give the dates: 请注意,我们正在上面的临时表中给出日期:

SELECT MONTH(m.month) AS monthno,
       MONTHNAME(m.month) as month_name,
       YEAR(m.month) as year,
       SUM(CASE WHEN `free_user` = 'y' THEN 1 ELSE 0 END) AS free_user,
       SUM(CASE WHEN `free_user` = 'n' THEN 1 ELSE 0 END) AS paid, 
       SUM(CASE WHEN `free_user` != '' THEN 1 ELSE 0 END) as total_users
FROM (
     select now() as month union 
     select date_sub(now(), INTERVAL 1 MONTH) as month union 
     select date_sub(now(), INTERVAL 2 MONTH) as month union 
     select date_sub(now(), INTERVAL 3 MONTH) as month union 
     select date_sub(now(), INTERVAL 4 MONTH) as month union 
     select date_sub(now(), INTERVAL 5 MONTH) as month union 
     select date_sub(now(), INTERVAL 6 MONTH) as month 
  ) AS m
LEFT JOIN tbl_agents as tb
   ON MONTH(tb.DATE_OF_REG) = MONTH(m.month)
GROUP BY MONTH(tb.DATE_OF_REG)
ORDER BY m.month DESC;

Output: 输出:

| monthno | month_name | year | free_user | paid | total_users |
|---------|------------|------|-----------|------|-------------|
|       1 |    January | 2018 |         1 |    0 |           1 |
|      12 |   December | 2017 |         1 |    1 |           2 |
|      11 |   November | 2017 |         1 |    0 |           1 |
|      10 |    October | 2017 |         0 |    0 |           0 |
|       9 |  September | 2017 |         0 |    1 |           1 |
|       8 |     August | 2017 |         1 |    0 |           1 |
|       7 |       July | 2017 |         0 |    1 |           1 |

You can see this in action in this fiddle: http://sqlfiddle.com/#!9/5ad682/12/0 您可以在此小提琴中看到它的作用: http ://sqlfiddle.com/#!9/ 5ad682/12/0

PHP PHP

The output required in your example is JSON - all you therefore need to do is grab the data from MySQL and build up an array representing the output, before converting to JSON. 您的示例中所需的输出是JSON-因此,您要做的就是从MySQL获取数据并建立一个表示输出的数组,然后再转换为JSON。 For example, it may look something like: 例如,它可能看起来像:

<?php

//$data = mysql_query_results

$output_array = array('month_of_registration'              => array(), 
                      'free_users_count_for_related_month' => array(), 
                      'paid_users_count_for_related_month' => array());

foreach( $data as $e ) {
   $output_array['month_of_registration'][] = $e['month_name'];
   $output_array['free_users_count_for_related_month'][] = $e['free_user'];
   $output_array['paid_users_count_for_related_month'][] = $e['paid'];
}

$output_data = json_encode($output_array);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM