【问题标题】:MySQL single query to count rows in multiple date rangesMySQL 单个查询以计算多个日期范围内的行数
【发布时间】:2016-04-21 08:01:50
【问题描述】:

我必须从 mysql 表中计算几个日期范围(今天、一周、一个月)中的行数。

目前我在我的 PHP 脚本中运行一个循环,并对每个日期范围进行单独的查询,我知道这是个坏主意。

<?php
$now = "2016-04-21";
$today = $now;
$week = date( 'Y-m-d', strtotime( '-7 day', strtotime( $now ) ) );
$month = substr( $now, 0, 7 );

$res1 = mysql_query("SELECT SUM(pageview) FROM statistics WHERE user = '$id' AND DATE_FORMAT( date, '%Y-%m-%d' ) = '$today'" );
$res2 = mysql_query("SELECT SUM(pageview) FROM statistics WHERE user = '$id' AND ( t.date BETWEEN ( '$week' ) AND ( '$today' ) )");
$res3 = mysql_query("SELECT SUM(pageview) FROM statistics WHERE user = '$id' AND DATE_FORMAT( t.date, '%Y-%m' ) = '$month'" );

所以我想使用 SINGLE QUERY 来做到这一点。

我找到了 count rows in multiple date rangesquery for grabbing multiple date ranges,但我不确定哪个是最好的,以及在我的情况下该怎么做

【问题讨论】:

  • 你能解释一下表的结构吗?你有什么专栏?等等,这样我就可以更好地了解您在做什么。
  • 表格有 4 列“id int(10) autoincrement primary”、“date date”、“user varchar(32) index”和“pageview int(10)”。在浏览量中存储每日浏览量的总数
  • 好吧,所以每一行都是一个有很多页面浏览量的用户,你可能会有很多这样的行,然后你想计算你在过去一个月、过去一周和过去一天,对吗?另外,您提到您当前正在执行循环。您的意思是您将用户的页面浏览量 1 个 1 加在一起吗?

标签: php mysql date


【解决方案1】:

如果您真的想使用一个查询来检索三个值:

$res = mysql_query("
SELECT sum1, sum2, sum3 
FROM (SELECT SUM(pageview) AS sum1 FROM statistics WHERE user = '$id' AND DATE_FORMAT( date, '%Y-%m-%d' ) = '$today') AS T1
JOIN (SELECT SUM(pageview) AS sum2 FROM statistics WHERE user = '$id' AND ( t.date BETWEEN ( '$week' ) AND ( '$today' ) )) AS T2
JOIN (SELECT SUM(pageview) AS sum3 FROM statistics WHERE user = '$id' AND DATE_FORMAT( t.date, '%Y-%m' ) = '$month') AS T3");

虽然这在性能方面并没有提高多少,但我真的没有理由这样做。

附:在这样的查询中插入变量是一个坏习惯。在这种情况下,您的安全,但如果您使用用户输入的变量,您对 SQL 注入持开放态度。尝试学习prepared statements

【讨论】:

  • 不,因为我需要三个单独的结果:今天、星期和月份。
  • 在这种情况下,您可以在一个查询中完成,但也可以在三个查询中完成。我认为这在代码方面更简洁,并且通过将其设为一个查询并不会提高效率
【解决方案2】:

您可以通过OR 组合所有条件,在一个查询中选择所有数据。而这种构造可以在SELECT中使用,对满足某些条件的行求和

SUM(IF(condition, sum_column_name, 0))

如果您想返回一行包含三个总和,您的查询可能如下所示

SELECT
  SUM(IF(t.date = '$today', pageview, 0)) AS pageview_today,
  SUM(IF(t.date BETWEEN '$week' AND '$today', pageview, 0)) AS pageview_week,
  SUM(IF(DATE_FORMAT(t.date, '%Y-%m') = '$month', pageview, 0)) AS pageview_month
FROM statistics t
WHERE user = '$id' AND (
  t.date = '$today'
  OR (t.date BETWEEN '$week' AND '$today')
  OR DATE_FORMAT(t.date, '%Y-%m') = '$month'
)

或者您可以进行 3 个查询并将它们与@quazardous 提到的UNION 结合起来。这个方法会给你3个不同的行。

【讨论】:

    【解决方案3】:

    使用联合?

    Select a from B
    Union
    Select B from C
    ...
    

    【讨论】:

      猜你喜欢
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-26
      • 2019-12-04
      • 1970-01-01
      相关资源
      最近更新 更多