2017-01-06 10 views
1

는 실제로 필요한 것 : QueryBuilder와 지난 달 돌려 기록을 Symfony2QueryBuilder를 사용하여 CURRENT_DATE()와 지난 달 사이의 일수 차이를 계산하는 방법은 무엇입니까?

에서 또는 다른 말로 : 내가 무슨 짓을 교리 QueryBuilder

created_at >= DATE_FORMAT(NOW(), '%Y-%m-%d') - INTERVAL 1 MONTH 

에 다음과 MySQL의 쿼리를 변환 :

$clicks = $clickRepo->createQueryBuilder('c') 
     ->select('c.product, c.createdAt, c.title') 
     ->addSelect('COUNT(c.product)') 
     ->where('c.type = :pro') 
      ->setParameter('pro', 'product') 
     ->andWhere('c.createdAt >= DATE_DIFF(CURRENT_DATE(), :end)') 
      ->setParameter('end', new \DateTime('-30 days'), \Doctrine\DBAL\Types\Type::DATETIME) 
     ->andWhere('c.shop != :null') 
      ->setParameter('null', '0') 
     ->andWhere('c.visible = :one') 
      ->setParameter('one', '1') 
     ->groupBy('c.product') 
     ->setMaxResults(2) 
     ->getQuery()->getResult(); 

esult는 :

array(1) { 
    [0]=> 
    array(4) { 
    ["product"]=> 
    int(3) 
    ["createdAt"]=> 
    object(DateTime)#3211 (3) { 
     ["date"]=> 
     string(26) "2016-02-19 13:27:45.000000" 
     ["timezone_type"]=> 
     int(3) 
     ["timezone"]=> 
     string(13) "Europe/Berlin" 
    } 
    ["title"]=> 
    string(23) "Title BlaBla" 
    ["clicks"]=> 
    string(1) "2" 
    } 
} 

이 테이블의 시작 부분 만 레코드를 반환합니다.

답변

0

방금 ​​등록했습니다. DQL function입니다.

DateAddFunction.php

# Bundle/ProductBundle/myDQL/DateAddFunction.php 
<?php 

namespace Bundle\ProductBundle\myDQL; 

use Doctrine\ORM\Query\Lexer; 
use Doctrine\ORM\Query\AST\Functions\FunctionNode; 

/** 
* DateAddFunction ::= 
*  "DATE_ADD" "(" ArithmeticPrimary ", INTERVAL" ArithmeticPrimary Identifier ")" 
*/ 
class DateAddFunction extends FunctionNode 
{ 
    public $firstDateExpression = null; 
    public $intervalExpression = null; 
    public $unit = null; 

    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 

     $this->firstDateExpression = $parser->ArithmeticPrimary(); 

     $parser->match(Lexer::T_COMMA); 
     $parser->match(Lexer::T_IDENTIFIER); 

     $this->intervalExpression = $parser->ArithmeticPrimary(); 

     $parser->match(Lexer::T_IDENTIFIER); 

     /* @var $lexer Lexer */ 
     $lexer = $parser->getLexer(); 
     $this->unit = $lexer->token['value']; 

     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
     return 'DATE_ADD(' . 
      $this->firstDateExpression->dispatch($sqlWalker) . ', INTERVAL ' . 
      $this->intervalExpression->dispatch($sqlWalker) . ' ' . $this->unit . 
      ')'; 
    } 
} 

config.yml

# app/config/config.yml 
doctrine: 
    orm: 
     auto_generate_proxy_classes: "%kernel.debug%" 
     auto_mapping: true 
     dql: 
      string_functions: 
       DATEADD: \Bundle\ProductBundle\myDQL\DateAddFunction 

쿼리

$clicks = $clickRepo->createQueryBuilder('c') 
    ->select('c.product, c.createdAt, c.title') 
    ->addSelect('COUNT(c.product)') 
    ->where('c.type = :pro') 
    ->setParameter('pro', 'product') 
    ->andWhere('c.createdAt >= DATEADD(CURRENT_DATE(), INTERVAL :minusOne MONTH)') 
    ->setParameter('minusOne', '-1') 
    ->andWhere('c.shop != :null') 
    ->setParameter('null', '0') 
    ->andWhere('c.visible = :one') 
    ->setParameter('one', '1') 
    ->groupBy('c.product') 
    ->setMaxResults(2) 
    ->getQuery()->getResult(); 
0

직접 MySQL을 사용 할 수 있습니다 'INTERVAL 1 MONTH'은 지난 한 달 데이터를 얻을 수 있습니다 :

$clicks = $clickRepo->createQueryBuilder('c') 
      ->select('c.product, c.createdAt, c.title') 
      ->addSelect('COUNT(c.product)') 
      ->where('c.type = :pro') 
       ->setParameter('pro', 'product') 
      ->andWhere('c.createdAt >= (NOW() - INTERVAL 1 MONTH)') 

      ->andWhere('c.shop != :null') 
       ->setParameter('null', '0') 
      ->andWhere('c.visible = :one') 
       ->setParameter('one', '1') 
      ->groupBy('c.product') 
      ->setMaxResults(2) 
      ->getQuery()->getResult(); 

는 희망이 도움이 ....

+0

1. 나는 질문 제목을 편집했다. Doctrine은 CURRENT_DATE() 만 지원합니다. 2.이 경우에도이 오류가 발생합니다 : [Doctrine \ ORM \ Query \ QueryException] [구문 오류] 행 0, 열 168 : 오류 : 예상 Doctrine \ ORM \ Query \ Lexer :: T_CLOSE_PARENTHESIS, 1 ' –

+0

3. 나는 당신에게도 당신의 모습에 문제가 있다고 경고해야합니다. c.createdAt> = (NOW(), INTERVAL 1 MONTH) –

1

DATE_DIFF()는 두 날짜 사이의 시간을 반환합니다. DATE_SUB() 함수를 사용해야한다고 생각합니다.

->andWhere('c.createdAt >= DATE_SUB(CURRENT_DATE(), :end)')

+0

이 경우이 오류가 발생합니다. [Doctrine \ ORM \ Query \ QueryException] [구문 오류] 줄 0, col170 : 오류 : 예상 Doctrine \ ORM \ Query \ Lexer :: T_COMMA, '있어' –