仅根据月份和年份选择 mySQL

我在 mySQLDB 中有一个列,它有一些行。其中一行是日期,如下所示: 2012-02-01

我想要实现的是只根据年份和月份使用 PHP 执行 SELECT。

SELECT 的逻辑如下:

$q="SELECT * FROM projects WHERE Date="SELECT HERE THE SPECIFIC YEAR AND MONTH"";

The specific month and year will be be passed from a $_POST variable, like this $_POST['period']="2012-02";

我该怎么做?

300118 次浏览
SELECT * FROM projects WHERE YEAR(Date) = 2011 AND MONTH(Date) = 5

其逻辑是:

SELECT * FROM objects WHERE Date LIKE '$_POST[period]-%';

LIKE操作员将选择以 $_POST['period']开始的所有行,然后是破折号和蒙特的日期

http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html - Some additional information

$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 并为 DB 节省一些工作。这样就可以有效地利用 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
);

EDIT
忘记了 Unix 时间戳转换。

If you have

$_POST['period'] = "2012-02";

首先,找到每月的第一天:

$first_day = $_POST['period'] . "-01"

然后,如果你有一个 Date上的索引,这个查询将使用一个:

$q = "
SELECT *
FROM projects
WHERE Date BETWEEN '$first_day'
AND LAST_DAY( '$first_day' )
" ;

还可以使用包含-排斥间隔,这种方法非常有效(不必担心列是 DATEDATETIME还是 TIMESTAMP,也不必担心精度:

$q = "
SELECT *
FROM projects
WHERE Date >= '$first_day'
AND Date  < '$first_day' + INTERVAL 1 MONTH
" ;

安全警告:

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

在这里,在 mySQL 中按 MONTH 和 DATE 查找记录

这是您的 POST 值 $_POST['period']="2012-02";

只是,爆破值由破折号 $Period = explode('-',$_POST['period']);

从爆炸值获取数组:

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

在 SQL 查询中输入值:

SELECT * FROM projects WHERE YEAR(Date) = '".$Period[0]."' AND Month(Date) = '".$Period[0]."';

按月份和年份计算结果。

是的,这是工作,但它只返回一行,而有几行检索使用选定的列只。 和 SELECT 标题一样,Date FROM mytable WHERE YEAR (Date) = 2017 AND MONTH (Date) = 09 returns only one row.

下面是我使用的一个查询,它将在一个周期内以总和的形式返回每条记录。

密码如下:

$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();
?>

这将列出每个 emp _ nr 以及它们所积累的每月小时数的总和。

假设您有一个数据库字段 create _ at,其中您从时间戳获取值。 您希望从 create _ at date 按年月进行搜索。

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

you can do it by changing $q to this:

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

似乎没有人在谈论性能,所以我在 sample database from Mysql上测试了两个最受欢迎的答案。该表具有2.8 M 行的结构

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
-----------------

我的结论

  1. BETWEEN在索引柱和非索引柱上的表现略好。
  2. 未编制索引的列略慢于编制索引的列。

从表中获取特定的月份和年份数据

SELECT * FROM table WHERE DATE_FORMAT(column_name,'%Y-%m') = '2021-06'

你可以使用 mysql 日期 _ 格式函数,只考虑日期的年月部分:

select * from table where DATE_FORMAT(column, '%Y%m') = '202105';