월 및 연도 기준으로 만 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

답변:


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

먼저 매월 1 일을 찾습니다.

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

그러면이 쿼리는 인덱스를 사용합니다 Date.

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

꽤 잘 작동하는 포괄적-배타적 간격을 사용할 수도 있습니다 (열이 DATE, DATETIME또는 또는 TIMESTAMP정밀도에 대해 걱정할 필요가 없습니다 .

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

보안 경고:

이러한 값을 적절하게 이스케이프하거나 준비된 문을 사용해야합니다. 요컨대, SQL 주입 문제를 피하기 위해 요즘 PHP에서 권장되는 방법을 사용하십시오.


2
예, 그 사이에 +1, 처음에는 Year + Month 함수를 사용했지만 확장하거나 인덱스를 사용하지 않았습니다.
sobelito 2015 년

@sobelito 그래. 나는 일반적으로 포괄적 인 간격을 선호합니다. 게시물이 업데이트되었습니다.
ypercubeᵀᴹ

이 값을 이스케이프하거나 준비된 문장을 사용하십시오 ... 😓
Jared

9

여기 있습니다. 컴퓨팅을 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
    );

편집
유닉스 타임 스탬프 변환을 잊어 버렸습니다.


색인 친화적이지만 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

2
작은 바비 테이블 누구?
Rob

항상 성능에 열중 할 필요는 없습니다. 때로는 몇 마이크로 초를 더 빠르게 작동시키기 위해 어떤 노력과 시간을 투자해도 아무런 차이가 없지만 그 시간을 잃었습니다.
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 Title과 마찬가지로 Date FROM mytable WHERE YEAR (Date) = 2017 AND MONTH (Date) = 09는 하나의 행만 반환합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.