Php 仅根据月份和年份选择mySQL

Php 仅根据月份和年份选择mySQL,php,mysql,Php,Mysql,我的mySQL数据库中有一列,其中有一些行。其中一行是日期,如下所示:2012-02-01 我想要实现的是使用PHP仅基于年份和月份进行选择 选择的逻辑如下所示: $q="SELECT * FROM projects WHERE Date="SELECT HERE THE SPECIFIC YEAR AND MONTH""; 特定的月份和年份将通过$\u POST变量传递,如$\u POST['period']=“2012-02” 我该怎么做?逻辑是: SELECT * FROM projec

我的mySQL数据库中有一列,其中有一些行。其中一行是日期,如下所示:
2012-02-01

我想要实现的是使用PHP仅基于年份和月份进行选择

选择的逻辑如下所示:

$q="SELECT * FROM projects WHERE Date="SELECT HERE THE SPECIFIC YEAR AND MONTH"";
特定的月份和年份将通过
$\u POST
变量传递,如
$\u POST['period']=“2012-02”

我该怎么做?

逻辑是:

SELECT * FROM projects WHERE YEAR(Date) = 2011 AND MONTH(Date) = 5
SELECT * FROM objects WHERE Date LIKE '$_POST[period]-%';
LIKE
操作符将选择所有以
$\u POST['period']
开头的行,然后选择破折号和月份日期

-一些附加信息

您可以这样做:

$q="SELECT * FROM projects WHERE YEAR(date) = 2012 AND MONTH(date) = 1;
$q="SELECT * FROM projects WHERE Year(Date) = '$year' and Month(Date) = '$month'";

从日期列获取月份和年份值的步骤

select year(Date) as "year", month(Date) as "month" from Projects

给你。将计算留给PHP,并为数据库节省一些工作。这样,您就可以有效地利用
Date
列上的索引

<?php
    $date = $_POST['period'];

    $start = strtotime($date);
    $end   = strtotime($date . ' 1 month - 1 second');

    $query = sprintf(
        'SELECT *
           FROM projects
          WHERE Date BETWEEN FROM_UNIXTIME(%u) AND FROM_UNIXTIME(%u)',
        $start,
        $end
    );
如果您有

$_POST['period'] = "2012-02";
首先,找到一个月的第一天:

$first_day = $_POST['period'] . "-01"
然后此查询将使用
日期的索引,如果您有:

$q = "
    SELECT *  
    FROM projects 
    WHERE Date BETWEEN '$first_day' 
                   AND LAST_DAY( '$first_day' )
     " ;
还可以使用包含-排除间隔,这非常有效(您不必担心列是否为
日期
日期时间
时间戳
,也不必担心精度:

$q = "
    SELECT *  
    FROM projects 
    WHERE Date >= '$first_day' 
      AND Date  < '$first_day' + INTERVAL 1 MONTH 
     " ;
$q=”
选择*
来自项目
其中日期>=“$first\u day”
日期<'第一天'+间隔1个月
" ;

安全警告:


您应该正确地转义这些值或使用预先准备好的语句。简言之,现在使用PHP中推荐的任何方法,以避免任何SQL注入问题。

在这里,在mySQL中按月份和日期查找记录

这是您的帖子值
$\u POST['period']=“2012-02”

只需按破折号分解值
$Period=explode('-',$\u POST['Period']);

从分解值获取数组:

数组
(
[0] => 2012
[1] => 02
)

将值放入SQL查询:

从年(日期)='“$Period[0]”和月(日期)='“$Period[0]”的项目中选择*;


按月份和年份获取结果。

是的,这是可行的,但它只返回一行,而仅使用选定列检索多行。 与选择标题一样,从mytable中选择日期,其中年份(日期)=2017,月份(日期)=09
只返回一行。

这里是我使用的查询,它将在一个期间内以总和的形式返回每条记录

代码如下:

$result = mysqli_query($conn,"SELECT emp_nr, SUM(az) 
FROM az_konto 
WHERE date BETWEEN '2018-01-01 00:00:00' AND '2018-01-31 23:59:59' 
GROUP BY emp_nr ASC");

echo "<table border='1'>
<tr>
<th>Mitarbeiter NR</th>
<th>Stunden im Monat</th>
</tr>";

while($row = mysqli_fetch_array($result))
{
$emp_nr=$row['emp_nr'];
$az=$row['SUM(az)'];
echo "<tr>";
echo "<td>" . $emp_nr . "</td>";
echo "<td>" . $az . "</td>";
echo "</tr>";
}
echo "</table>";
$conn->close();
?>
$result=mysqli\u query($conn),选择emp\u nr,SUM(az)
来自az_konto
其中日期介于“2018-01-01 00:00:00”和“2018-01-31 23:59:59”之间
由emp_nr ASC)组成的集团;
回声“
米塔贝特NR
蒙纳特特登酒店
";
while($row=mysqli\u fetch\u数组($result))
{
$emp_nr=$row['emp_nr'];
$az=$row['SUM(az)';
回声“;
回声“$emp_nr.”;
回声“$az.”;
回声“;
}
回声“;
$conn->close();
?>

这将列出每个emp\u nr以及它们累积的每月小时数之和。

假设您创建了一个数据库字段,从中获取时间戳的值。 您希望从创建日期开始按年和月进行搜索

YEAR(date(created_at))=2019 AND MONTH(date(created_at))=2

您可以将$q更改为以下内容:

$q="SELECT * FROM projects WHERE YEAR(date) = $year_v AND MONTH(date) = $month_v;

似乎没有人在谈论性能,所以我在一张表上测试了两个最流行的答案。该表有280万行结构

CREATE TABLE `salaries` (
  `emp_no` int(11) NOT NULL,
  `salary` int(11) NOT NULL,
  `from_date` date NOT NULL,
  `to_date` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `salaries`
  ADD PRIMARY KEY (`emp_no`,`from_date`);
以下是执行的测试和结果

SELECT * FROM `salaries` WHERE YEAR(from_date) = 1992 AND MONTH(from_date) = 6
12339 results
-----------------
11.5 ms 
12.1 ms
09.5 ms
07.5 ms
10.2 ms
-----------------
10.2 ms Avg
-----------------


SELECT * FROM `salaries` WHERE from_date BETWEEN '1992-06-01' AND '1992-06-31'
-----------------
10.0 ms
10.8 ms
09.5 ms
09.0 ms
08.3 ms
-----------------
09.5 ms Avg
-----------------


SELECT * FROM `salaries` WHERE YEAR(to_date) = 1992 AND MONTH(to_date) = 6
10887 results
-----------------
10.2 ms
11.7 ms
11.8 ms
12.4 ms
09.6 ms
-----------------
11.1 ms Avg
-----------------


SELECT * FROM `salaries` WHERE to_date BETWEEN '1992-06-01' AND '1992-06-31'
-----------------
09.0 ms
07.5 ms
10.6 ms
11.7 ms
12.0 ms
-----------------
10.2 ms Avg
-----------------
我的结论

  • BETWEEN
    在索引列和未索引列上都略好
  • 未索引列的速度略慢于索引列

  • 您可以对内部表示为整数的数据使用语句间-1字符串操作!?您是认真的吗?@Yaroslav是的,效率很高,我想:没有索引的数据。它首先将日期值转换为字符串,然后再匹配该字符串。在MySQL中,任何列类型都可以通过LIKE查询。但它仍然可以工作:DLittle bobby tables有人吗?有人吗现在,你不必一直为性能而疯狂。有时,你投入的精力和时间使它工作快几微秒并没有任何区别,但你浪费了时间。你的查询无法扩展,因为它需要进行完整的表扫描,除非MySQL中有一些我不知道的优化。不是吗对于
    EXTRACT(从日期算起的年\月)
    ?它是索引友好的,但是strotime会给您int,您需要首先将它转换为mysql的日期。它应该是字符串连接,而不是求和操作:
    $end=strotime($Date.'1个月-1秒'))
    是的,+1对于中间值,我最初使用的是年+月函数,但这类函数不可缩放,也不使用索引。@sobelito是的。我通常更喜欢包含的独占间隔。更新后。请转义这些值或使用准备好的语句……这也不使用索引