2014-11-10 2 views
4

Ok У меня есть 2 таблицы, соответствующая структура выглядит следующим образом:DQL сложный запрос

**youtubevideo** 
id - int 
allViews - relational 


**views** 
id - int 
youtubevideo_id - int 
viewCount - int 
firstFetch - date 

Его отношение, что youtubevideo имеет много точек зрения. Это представлено OneToMany в организации Symfony.

Теперь у меня есть 2 даты, давайте назовите их fromDate и toDate. Мне нужно выбрать все youtubevideos и заказать их по сумме viewCount видов, которые принадлежат им.

И я хочу использовать только те точки зрения, которые имеют дату firstFetch, между fromDate и toDate.

Так что я предполагаю, что это будет что-то вроде

SELECT y FROM YTScraperBundle:YouTubeVideo y 
JOIN y.allViews v GROUP BY y.id 
ORDER BY SUM(v.viewCount) LIMIT 0, 30; <-- or does this need to be an inline select to the specific element? 

И я не вижу, как поставить WHERE v.firstFetch между FromDate и Todate там.

UPDATE

$query = $this->em->createQuery(
    "SELECT y, IF(v IS NULL, 0, SUM(v.viewCount)) AS HIDDEN sumviewcount 
    FROM YTScraperBundle:YouTubeVideo y 
    LEFT JOIN y.allViews v WITH v.firstFetch BETWEEN :fromDate AND :toDate 
    GROUP BY y ORDER BY sumviewcount DESC 
    " 
); 
$query->setMaxResults(self::PR_PAGE); 
$query->setFirstResult($firstResult); 
$query->setParameter('fromDate', $fromDate); 
$query->setParameter('toDate', $toDate); 

Получение ошибки:

Expected known function, got 'IF' 

ответ

3

Вы должны использовать WITH, BETWEEN, и связать два DateTime объектов в параметризованного запроса:

$result = $this->getDoctrine()->getManager()->createQuery(' 
    SELECT y, 
     CASE WHEN (v IS NULL) THEN 0 ELSE SUM(v.viewCount) END AS HIDDEN sumviewcount 
    FROM YTScraperBundle:YouTubeVideo y 
    LEFT JOIN y.allViews v WITH v.firstFetch BETWEEN :fromDate AND :toDate 
    GROUP BY y ORDER BY sumviewcount DESC 
')->setParameter('fromDate', new \DateTime('12-34-5678 00:00:00')) // Replace this with an ISO date 
->setParameter('toDate', new \DateTime('12-34-5678 00:00:00')) // Replace here too 
->getResult(); 

я 've combined @Matteo's answer concerning the SUM into mine for posterity. Кредит достается ему за идею HIDDEN.

+0

У меня возникли проблемы с этим возвращение 1 ряд, кроме того, он должен еще получить youtubevideos, даже если они имеют 0 просмотров связанные, вид должен просто не быть прикреплены к нему, если это делает sense :) –

+0

@IvanRistic Давайте сначала рассмотрим проблему 0 и посмотрим, решает ли она проблему с 0 строками. 'JOIN' по умолчанию' INNER JOIN', поэтому мы должны явно называть 'LEFT JOIN'. См. Мое редактирование. Обратите внимание, что 'v.viewCount' будет' NULL' в пустых объединениях, так что это может создать еще одну проблему ... – sjagr

+0

Теперь я получаю очень странную проблему, сортировка ведет себя очень странно, не работает, а дата не фильтруется: $ запроса = $ этом-> em-> CreateQuery ( «SELECT у, СУММА (v.viewCount) как скрытые sumviewcount ОТ YTScraperBundle: YouTubeVideo у LEFT JOIN y.allViews В с v.firstFetch МЕЖДУ: FromDate И: Todate GROUP BY y ORDER BY sumviewcount DESC " ); –

3

Для сортировки вы можете использовать функции Doctrine2 HIDDEN (доступные с Doctrine 2.2+).

SELECT y, 
     SUM(v.viewCount) AS HIDDEN sumviewcount 
FROM YTScraperBundle:YouTubeVideo y 
JOIN y.allViews v 
GROUP BY y 
ORDER BY sumviewcount 
LIMIT 0, 30; 

Посмотрите на статью this.

Надежда эта помощь

+0

По какой-то причине это возвращает только одну строку –

+0

Извините, мой псевдокод попробовал удалить инструкцию 'distinct' или добавить' group by y' – Matteo

+0

Спасибо! Это работает для просмотров, теперь я просто попытаюсь реализовать предложение BETWEEN :)! –

Смежные вопросы