PHP查询今日、昨日,本月、上月信息数量函数

本文介绍了一个用于统计特定时间范围内论坛主题数量的PHP函数。该函数通过不同的参数设置可以返回当天、昨天、本月或上个月的主题数。文章详细解释了如何根据时间条件构造SQL查询语句来获取所需的数据。
function get_zhuti($cid,$day_num='',$addtime='')
{
/*
0 当天
-1 昨天
30 本月
-30 上月
*/
if ($addtime == ''){
$addtime = time();
}
if ($cid != ''){
$where="where cid=$cid";
}else{
$where="where 1=1";
}


if ($day_num == ''){
$sql1 = "select count(tid) AS num from tay_thread $where";
}
if ($day_num == "0"){
    $sql1 = "select count(tid) AS num  from tay_thread where to_days(date_format(from_UNIXTIME(`addtime`),'%Y-%m-%d')) = to_days(now())";
}
if ($day_num == "-1"){
    $beginYesterday = mktime(0, 0, 0, date("m"), date("d") -1, date("Y")); 
    $endYesterday = mktime(0,0,0,date("m") ,date("d"),date("Y"));//
    $sql1 = "SELECT count(tid) AS num FROM tay_thread WHERE  addtime BETWEEN '$beginYesterday' AND '$endYesterday'";
//echo $beginYesterday;
//echo "<br/>";
//$lll = date('Y-m-d H:i:s', $beginYesterday);
//echo $lll;
//echo "<br/>";
//$sss = date('Y-m-d H:i:s', $endYesterday);
//echo $sss;
//exit;
}
if ($day_num == "30"){
$beginThismonth = mktime(0, 0, 0, date("m"), 1, date("Y"));
$endThismonth = mktime(23, 59, 59, date("m"), date("d"), date("Y"));
    $sql1 = "SELECT count(tid) AS num FROM tay_thread WHERE addtime BETWEEN '$beginThismonth' AND '$endThismonth' ";


}
if ($day_num == "-30"){
$beginThismonth = mktime(0, 0, 0, date("m")-1, 1, date("Y"));
$endThismonth = mktime(23, 59, 59, date("m"), date("d")-date("d"), date("Y"));
    $sql1 = "SELECT count(tid) AS num FROM tay_thread WHERE addtime BETWEEN '$beginThismonth' AND '$endThismonth' ";
}


$result1=mysql_query($sql1);
$zhuti=mysql_fetch_array($result1);
    $page = array();
$page['num']      = $zhuti[0];
    return $page;
}
<think>我们有两个需求:查询当月数据和查询上月有但本月没有的数据。 根据引用[1]和引用[2],查询当月数据可以使用: WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM') 或者使用引用[3]中的方法,用条件表达式进行统计,但这里我们只需要查询数据。 对于查询上月本月无的数据,我们可以采用集合差集(MINUS)的方式,但需要注意:如果表很大,这种方式可能效率不高。 另一种方法是使用NOT EXISTS子查询,这样可能更高效。 具体思路: 1. 查询上月有:TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'YYYY-MM') 2. 并且在本月中不存在相同标识(比如主键)的记录,或者更确切地说,同一标识(比如某个业务键)在上月出现但在本月没有出现。但是,这里没有提到具体的业务键,所以我们只能通过日期范围来判定。 然而,题目要求的是“上月本月没有的数据”,这里的数据是指整条记录,而不是某个业务实体。所以,我们可以这样理解:找出所有上月的记录,然后排除那些在本月也出现的记录(但注意:同一条记录不可能出现在两个月,因为日期字段是固定的)。因此,实际上我们只需要查询上月的记录,然后排除那些日期字段被更新为本月的记录?这不太符合常理。 实际上,这里可能是指同一个业务实体(例如同一个客户或同一个产品)在上月有记录(交易记录等)而本月没有。但是问题中没有明确业务实体,所以我们需要假设表中有唯一标识每条记录的主键,或者我们比较整条记录。 如果直接比较整条记录,我们可以使用MINUS(集合差),因为MINUS会比较两个结果集的所有列。 但是,如果表很大,使用MINUS可能效率较低。另一种方法是使用NOT EXISTS,但需要有一个可以关联的条件,比如某个业务键(例如客户ID)在上月出现而本月没有出现,但这里我们没有业务键,所以只能按整条记录来排除。 然而,实际上,一条记录不可能同时出现在两个月(因为日期字段不同),所以我们查询上月的记录时,这些记录本身就不会出现在本月。那么为什么还要减去本月?这是因为我们可能担心一条记录被错误地标记到上个月,同时也出现在本月?这不太可能。 所以,重新审视需求:“上月本月无的数据”可能是指同一个业务主体(比如同一个客户)在上月有记录而本月没有记录,而不是同一条记录。如果是这样,那么我们需要一个业务标识(比如客户ID)来关联。 但是问题中没有给出具体的表结构,所以有两种理解: 1. 找出所有在上月出现过的记录(按记录本身),这些记录不会出现在本月(因为日期不同),所以直接查询上月即可?这显然不是用户想要的。 2. 找出那些在上月有活动(有记录)但在本月没有活动的业务实体(例如客户)。 由于问题描述不够清晰,我将提供两种方案: 方案一(按整条记录比较,适用于需要找出上月的记录且这些记录不在本月出现,但通常这种情况不存在): 实际上,一条记录只能属于一个月(由日期字段决定),所以直接查询上月的数据就是“上月有”的数据,而本月的数据就是本月有。那么“上月本月无”就是上月的所有记录(因为本月不可能有上月的记录)。但这似乎没有实际意义。 因此,我推测用户的需求可能是:在同一个表中,有一些业务实体(比如客户),在上月有记录,而在本月没有记录。那么就需要按业务实体分组。 方案二(按业务实体): 假设表中有业务实体的标识(比如customer_id),那么我们可以这样: 1. 找出上月的所有业务实体(distinct customer_id) 2. 找出本月的所有业务实体(distinct customer_id) 3. 然后找出那些出现在上月但不出现在本月的业务实体。 但是问题没有给出业务实体,所以无法按此进行。 回顾用户的问题:“查询当月数据和上月本月没有的数据”。结合引用[1][2][3]都是按日期字段直接过滤,没有提到业务实体,所以可能用户就是想要查询上月的全部记录(因为本月自然不会有上月的记录)。那么“上月本月没有”实际上就是上月的全部记录。但这显然不是用户想要的,因为用户将两个需求分开:一个是当月数据,另一个是“上月本月无”。 所以我们再仔细分析:需求“上月本月没有的数据”可能是指在同一个业务周期内(比如同一个客户)在上月有交易记录而本月没有。这时,我们需要一个业务标识。 由于问题中没有明确,这里我假设用户的需求是按整条记录来比较(即记录出现在上月但不出现在本月),但实际上,由于每条记录都有一个日期字段,所以一条记录只能属于一个月。因此,我建议用户澄清需求。 但是,根据常见业务需求,我猜测用户可能想要统计的是:某个实体(例如客户、产品等)在上月有记录而本月没有记录。因此,我们需要一个业务标识字段。 不过,在用户没有提供表结构的情况下,我将给出两种情况的解决方案: 情况1:按整条记录比较(使用MINUS) 查询当月数据: SELECT * FROM table_name WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM'); 查询上月本月无的数据(实际上就是上月的所有记录,因为本月的记录日期不可能等于上月): SELECT * FROM table_name WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(ADD_MONTHS(SYSDATE,-1), 'YYYY-MM'); 但是这样两个结果集是独立的,并没有“本月没有”这个条件,因为本月的记录不会出现在上月的结果中。 情况2:按业务实体(例如客户ID)统计 假设表中有业务实体标识字段(比如customer_id),那么: 查询当月数据(同一业务实体的记录可能有多条,但我们这里只查记录,所以直接按日期): SELECT * FROM table_name WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM'); 查询上月有而本月无的业务实体(注意:是业务实体,不是记录): SELECT DISTINCT customer_id FROM table_name WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'YYYY-MM') MINUS SELECT DISTINCT customer_id FROM table_name WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM'); 或者使用NOT EXISTS: SELECT DISTINCT t1.customer_id FROM table_name t1 WHERE TO_CHAR(t1.date_column, 'YYYY-MM') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'YYYY-MM') AND NOT EXISTS ( SELECT 1 FROM table_name t2 WHERE TO_CHAR(t2.date_column, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM') AND t2.customer_id = t1.customer_id ); 由于用户的问题没有明确,我将提供两种可能的解释,并以情况1(按整条记录)作为基础,同时补充情况2(按业务实体)的方法。 考虑到引用中都是按日期直接过滤,没有涉及业务实体,我们先按情况1回答。 但是,用户之前的问题提到“上月本月没有的数据”,而引用[3]中有一个统计的例子,它使用了条件聚合,但也没有涉及业务实体。所以,我决定按照整条记录来查询,即直接查询上月的数据(因为本月不可能有上月的记录),这就是“上月有而本月无”的数据? 然而,这不符合逻辑,因为用户要求的是“上月本月没有”,如果直接查询上月数据,那么它自然本月不会有(因为日期是上月的)。所以,我怀疑用户可能想要的是:同一个业务实体在上月有记录而本月没有。 由于用户在上一个问题中并没有提到业务实体,为了安全起见,我将提供两种方法,并说明适用场景。 因此,最终回答结构: 1. 查询当月数据(直接按日期) 2. 查询上月数据(直接按日期)——这就是“上月有”的数据 3. 解释:如果需求是同一个业务实体,则需要额外的业务标识字段,并给出查询方法 同时,根据引用[1]和[2],我们可以使用ADD_MONTHS函数来获取上个月的日期。 根据引用[3],我们也可以使用条件表达式,但这里我们只需要查询记录,所以不用聚合。 具体SQL如下: </think>### 查询当月数据的方法 在Oracle中查询当月数据,可通过比较日期字段的格式化值与当前年月实现。以下是推荐方法: ```sql SELECT * FROM your_table WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM'); ``` - **核心逻辑**:使用`TO_CHAR(date_column, 'YYYY-MM')`将日期字段格式化为年月,并与`TO_CHAR(SYSDATE, 'YYYY-MM')`比较 - **参数说明**: - `your_table`:目标表名 - `date_column`:日期类型字段名 - **优化技巧**:如果日期字段已建立索引,可改用范围查询提升性能: ```sql SELECT * FROM your_table WHERE date_column >= TRUNC(SYSDATE, 'MM') -- 本月第一天 AND date_column < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1); -- 下月第一天 ```[^1][^2] ### 查询上月本月无的数据的方法 #### 方案1:使用NOT EXISTS(推荐) ```sql SELECT * FROM your_table t1 WHERE TO_CHAR(t1.date_column, 'YYYY-MM') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'YYYY-MM') -- 上月数据 AND NOT EXISTS ( SELECT 1 FROM your_table t2 WHERE TO_CHAR(t2.date_column, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM') -- 本月数据 AND t2.key_column = t1.key_column -- 关键字段匹配 ); ``` - **优势**:避免全表扫描,通过关键字段关联提升性能 - **关键参数**: - `key_column`:业务唯一标识字段(如订单ID、用户ID等) #### 方案2:使用MINUS集合运算 ```sql SELECT key_column, date_column, ... -- 需明确列出所有字段 FROM your_table WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'YYYY-MM') -- 上月数据 MINUS SELECT key_column, date_column, ... -- 字段顺序/数量必须完全一致 FROM your_table WHERE TO_CHAR(date_column, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM'); -- 本月数据 ``` - **适用场景**:无唯一业务标识字段时 - **注意**: 1. 必须显式列出所有字段 2. 字段顺序必须完全一致 3. 大数据量时性能较低[^2][^3] ### 关键函数说明 | 函数 | 示例 | 作用 | |------|------|------| | `TO_CHAR(date, 'YYYY-MM')` | `TO_CHAR(SYSDATE, 'YYYY-MM') → '2023-10'` | 日期转年月字符串 | | `ADD_MONTHS(date, n)` | `ADD_MONTHS(SYSDATE, -1)` | 日期加减月份 | | `TRUNC(date, 'MM')` | `TRUNC(SYSDATE, 'MM')` | 截取到当月第一天 | ### 实际应用示例 统计客户上月有订单本月无订单: ```sql SELECT customer_id, customer_name FROM orders WHERE TO_CHAR(order_date, 'YYYY-MM') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'YYYY-MM') AND NOT EXISTS ( SELECT 1 FROM orders WHERE TO_CHAR(order_date, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM') AND customer_id = orders.customer_id ); ```[^3]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值