仅根据月份和年份选择mySQL


102

我的mySQL DB中有一列,其中有一些行。此行之一是DATE,如下所示:2012-02-01

我要实现的是仅基于年份和月份使用PHP进行SELECT。

SELECT的逻辑如下:

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

特定的月份和年份将通过这样的$_POST变量传递$_POST['period']="2012-02";

我该怎么做?


2
您可以使用BETWEEN语句
Ben Carey'2

Answers:


208
SELECT * FROM projects WHERE YEAR(Date) = 2011 AND MONTH(Date) = 5

5
您的查询无法扩展,因为它需要进行全表扫描,除非我不知道MySQL中的一些优化。
aefxx

2
这是真的EXTRACT(YEAR_MONTH FROM Date)吗?
cmbuckley

19

如果你有

$_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注入问题。


2
是的,在+1之间,我最初使用的是Year + Month函数,但这种方法无法扩展,也没有使用索引。
sobelito

@sobelito是的。我通常更喜欢包含与排除的间隔。发布更新。
ypercubeᵀᴹ

请转义这些值或使用准备好的语句...😓–
Jared

9

干得好。将计算工作留给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
    );

编辑
忘记了Unix时间戳转换。


它是索引友好的,但是strtotime为您提供了int,您需要首先将其转换为适用于mysql的日期。
piotrm

它应该是字符串连接,而不是求和运算:$end = strtotime($date .' 1 month - 1 second');
Konstantin Pereiaslov

6
$q="SELECT * FROM projects WHERE YEAR(date) = 2012 AND MONTH(date) = 1;

6

假设您有一个数据库字段created_at,您将从此处获取时间戳的值。您要从created_at日期按年和月进行搜索。

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

3

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

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

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

从爆炸值获取数组:

Array ( [0] => 2012 [1] => 02 )

将值放在SQL查询中:

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

通过MONTH和YEAR获取结果。


2

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

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


1

逻辑将是:

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

LIKE运营商将选择与开始的所有行$_POST['period']的山的天,随后为破折号和

http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html-一些其他信息


4
-1对内部表示为整数的数据进行字符串操作!你是认真的?
aefxx

@Yaroslav是的,高效,我想:D
aefxx

2
没有索引。它首先将日期值转换为字符串,然后匹配该字符串。在MySQL中,LIKE可以查询任何列类型。但仍然可以使用:D
Yaroslav 2013年

2
小鲍比桌子有人吗?
罗布(Rob)2015年

现在,您无需一直为性能而疯狂。有时,您投入一些精力和时间使它更快地运行几微秒并没有什么不同,但是您却浪费了时间。
赫里斯托(Hristo Petev)2015年

0

这是我使用的查询,它将在一段时间内返回总和的每条记录。

这是代码:

$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以及它们累计的每月小时数的总和。


0

您可以通过将$ q更改为此:

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

-1

是的,这是可行的,但是它仅返回一行,而只有几行要使用选定的列进行检索。与SELECT标题类似,mytable WHERE YEAR(Date)= 2017和MONTH(Date)= 09的日期仅返回一行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.