我目前正在进行过去6个月的跟进,但似乎可以做得更好(更少的代码行,可能更优化)
$monthones = mktime(0, 0, 0, date("n") - 1, 1);
$monthonef = mktime(0, 0, 0-1, date("n"), 1);
$query = "SELECT COUNT(*) FROM users WHERE type = '1' AND status = '1' AND (date >= '".$monthones."' AND date <= '".$monthonef."');";
$result = $pdo->query($query);
$monthone = $result->fetchColumn();
$query = "SELECT COUNT(*) FROM users WHERE type = '3' AND status = '1' AND (date >= '".$monthones."' AND date <= '".$monthonef."');";
$result = $pdo->query($query);
$monthone2 = $result->fetchColumn();
$monthtwos = mktime(0, 0, 0, date("n") - 2, 1);
$monthtwof = mktime(0, 0, 0-1, date("n") - 1, 1);
$query = "SELECT COUNT(*) FROM users WHERE type = '1' AND status = '1' AND (date >= '".$monthtwos."' AND date <= '".$monthtwof."');";
$result = $pdo->query($query);
$monthtwo = $result->fetchColumn();
$query = "SELECT COUNT(*) FROM users WHERE type = '3' AND status = '1' AND (date >= '".$monthtwos."' AND date <= '".$monthtwof."');";
$result = $pdo->query($query);
$monthtwo2 = $result->fetchColumn();
我有4个月的休息时间。有什么建议我可以改进吗?我在考虑组合查询并在循环结果时开始计数?或者会更糟糕?
答案 0 :(得分:0)
您可以使用conditional aggregation
返回单个查询中的所有计数:
select count(case when type = '1' AND
date >= '".$monthones."' AND date <= '".$monthonef."' then 1 end) cnt1,
count(case when type = '3' AND
date >= '".$monthones."' AND date <= '".$monthonef."' then 1 end) cnt2,
count(case when type = '1' AND
date >= '".$monthtwos."' AND date <= '".$monthtwof."' then 1 end) cnt3,
count(case when type = '3' AND
date >= '".$monthtwos."' AND date <= '".$monthtwof."' then 1 end) cnt4
from users
where status = '1'
答案 1 :(得分:0)
您只需使用一个SQL查询即可解决此问题。 请试试这个:
select count(case when type= '1' then 1 end) type_one
, count(case when type= '3' then 1 end) type_three
, DATE_FORMAT(FROM_UNIXTIME(date),'%Y-%m') month
from users
where status = '1'
and date between UNIX_TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -6 MONTH)) and UNIX_TIMESTAMP(CURDATE())
group by DATE_FORMAT(FROM_UNIXTIME(date),'%Y-%m')
您可以使用参数替换CURDATE()。
答案 2 :(得分:0)
似乎对数据库运行一个查询会更有效,一个传递数据。
对于日期范围条件,而不是减去秒,并使用
<= last second of month
我更喜欢使用
模式< first second of following month
如果原始代码中的逻辑对于生成&#34; start&#34;并且&#34;完成&#34;边界,我们只需要七个边界值,即每个月的第一个:
$month00 = mktime(0, 0, 0, date("n") - 0, 1);
$month01 = mktime(0, 0, 0, date("n") - 1, 1);
$month02 = mktime(0, 0, 0, date("n") - 2, 1);
$month03 = mktime(0, 0, 0, date("n") - 3, 1);
$month04 = mktime(0, 0, 0, date("n") - 4, 1);
$month05 = mktime(0, 0, 0, date("n") - 5, 1);
$month06 = mktime(0, 0, 0, date("n") - 6, 1);
然后查询可以是这样的:
$query = "
SELECT SUM(u.type = '1' AND u.date >= '$month01' AND u.date < '$month00') AS monthone
, SUM(u.type = '3' AND u.date >= '$month01' AND u.date < '$month00') AS monthone2
, SUM(u.type = '1' AND u.date >= '$month02' AND u.date < '$month01') AS monthtwo
, SUM(u.type = '3' AND u.date >= '$month02' AND u.date < '$month01') AS monthtwo2
, ...
, ...
, SUM(u.type = '1' AND u.date >= '$month06' AND u.date < '$month05') AS monthsix
, SUM(u.type = '3' AND u.date >= '$month06' AND u.date < '$month05') AS monthsix2
FROM users u
WHERE u.status = '1'
AND u.type IN ('1','3')
AND u.date >= '$month06'
AND u.date < '$month00'
";
...
将被重复表达式模式替换为monththree
/ monththree2
,monthfour
/ monthfour2
,monthfive
/ monthfive2
请注意,这使用MySQL简写,SUM()聚合内的表达式计算为1(如果条件为TRUE)或0(如果条件为FALSE)或NULL。
我们必须获取整行才能获得所有计数。我们不得不放弃fetchColumn()
并改为使用fetch()
。
$result = $pdo->query($query);
$row = $result->fetch(PDO::FETCH_ASSOC);
如果我们需要标量变量中的值,那么我们就不必更改后续代码:
$monthone = $row['monthone'];
$monthone2 = $row['monthone2'];
$monthtwo = $row['monthtwo'];
$monthtwo2 = $row['monthtwo2'];
...
...
$monthsix = $row['monthsix'];
$monthsix2 = $row['monthsix2'];