Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SF2][Symfony2][Symfony] setParameter nie działa w SELECT RepositoryClass
Forum PHP.pl > Forum > PHP > Frameworki
damianooo
Mam taki SQL:

  1. SELECT
  2. count(u.id) AS seasons,
  3. u.username AS username,
  4. sum(s.position = 1) AS wins,
  5. sum(s.totalPoints) AS totalpoints,
  6. sum(s.numOfQue) AS numOfQue,
  7. (sum(s.totalPoints)/sum(s.numOfQue)) AS avgPtsForMatch
  8. FROM statistics s
  9. INNER JOIN users u ON s.user_id = u.id
  10. GROUP BY u.username
  11. ORDER BY avgPtsForMatch DESC


Który w klasie Repository zrobiłem tak:

  1. public function getRanking(){
  2. $qb = $this->createQueryBuilder('s');
  3. $qb->select(
  4. 'u.username AS username'
  5. ,'(sum(s.totalPoints)/sum(s.numOfQue)) AS avgPtsForMatch'
  6. ,'count(u.id) AS seasons'
  7. ,'sum(s.numOfQue) AS numOfQue'
  8. ,'sum(s.totalPoints) AS totalpoints'
  9. ,'sum(s.position = :win) AS wins'
  10. )
  11. ->innerJoin('s.user', 'u')
  12. ->groupBy('u.username')
  13. ->orderBy('avgPtsForMatch', 'DESC')
  14. ->setParameter('win', 1)
  15. ;


Niestety zapis : ,'sum(s.position = :win) AS wins' nie działa wywalając błąd:

[Syntax Error] line 0, col 240: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '='

Jak to powinienem zrobić ?
lukaskolista
Wywala błąd bo składnia funkcji agregującej SUM nie przewiduje wciskania jako jej argument warunku. W tej chwili Twoje zapytanie (z tym warunkiem w SUM) jest składniowo oraz logicznie niepoprawne.
damianooo
ale zapytanie SQL jak wpiszę w phpmyadmina to działa - nie mam informacji że jest to składniowo nielogiczne itd.
Rozumiem że składania w Symfony nie przyjmuje takiej konstukcji.
Jak to można zapisać ?
lukaskolista
Nie tyle składnia symfony, co DQL w Doctrine
Szczerze mówiąc od dawna nie robiłem nic związanego z bazami danych w symfony, więc jedyne co mogę poradzić to użyć native SQL. Minus jset taki, że pewnie nie przełączysz się łatwo z MySQL na inną bazę.
damianooo
przełączać się na inną bazę nie będę ...

Poczekam jeszcze trochę ... może ktoś będzie wiedział jak inaczej to zrobić z użyciem DQL Doctrine ?
Gothicbezimienny
skoro to liczba to może spróbuj :

  1. ,'sum'('s.position = ?1') AS wins'


  1. ->setParameter(1, 1)
damianooo
nie działa niestety sad.gif ...

to na pewno jest taki zapis ? (chodzi mi o apostrofy)

  1. ,'sum'('s.position = ?1') AS wins'


a nie tak czasem ? :

  1. ,'sum(s.position = ?1) AS wins'
Gothicbezimienny
Tu masz eleganco opisane jak powinno to wyglądać porównaj http://symfony.com/doc/current/doctrine.html

Jak dla mnie nie masz informacji z jakiej tabeli to pbobierasz:

  1. FROM AppBundle:statistics s



na koncu jeszcze dodaj
  1.  
  2. $zmienna = $query->getResult();
damianooo
mam tak , używam Doctrine... cała metoda wygląda tak:

  1. public function getRanking(){
  2. $qb = $this->createQueryBuilder('s');
  3. $qb->select(
  4. 'u.username AS username'
  5. ,'(sum(s.totalPoints)/sum(s.numOfQue)) AS avgPtsForMatch'
  6. ,'count(u.id) AS seasons'
  7. ,'sum(s.numOfQue) AS numOfQue'
  8. ,'sum(s.totalPoints) AS totalpoints'
  9. ,'sum(s.position = ?1) AS wins'
  10. )
  11. ->innerJoin('s.user', 'u')
  12. ->groupBy('u.username')
  13. ->orderBy('avgPtsForMatch', 'DESC')
  14. ->setParameter(1, 1)
  15. ;
  16.  
  17. $result = $qb->getQuery()->getResult();
  18. return $result;
  19.  
  20. }
Gothicbezimienny
nadal brakuje FROM

$repository = $this->getDoctrine()
->getRepository('AppBundle:statistics ');
damianooo
FROMa tu nie trzeba ...

wystarczy zrobić tak:

  1. $qb = $this->createQueryBuilder('s');


ponieważ to jest w klasie repozytorium dla entity Statistic:

  1. namespace My\AppBundle\Repository;
  2. use Doctrine\ORM\EntityRepository;
  3.  
  4. class StatisticRepository extends EntityRepository {


a w kontrolerze mam dokładnie tak jak napisałeś:

  1. $repository = $this->getDoctrine()->getRepository('MyAppBundle:Statistic');
  2. $stats = $repository->getRanking();
Gothicbezimienny
Nie mogłem tego wiedzieć ze masz to gdzieś.
damianooo
Będę to musiał chyba w kodzie obrobić jakoś bo DQL Doctrine tak tego nie łyknie ...

Twój pomysł jest do zastosowania chyba tylko po słowie WHERE ale przed nie będzie działał - a szkoda bo czysty SQL taki zapis:

  1. sum(s.position = 1) AS wins,


to łyka bez problemu sad.gif
Turson
Spróbuj zamiast 's.position = 1' wstawić tam podzapytanie
aras785
  1. SUM(IF(s.position = :win, s.position, 0)) AS wins
damianooo
zmieniłem na :

  1. $qb = $this->createQueryBuilder('s');
  2. $qb->select(
  3. 'u.username AS username'
  4. ,'(sum(s.totalPoints)/sum(s.numOfQue)) AS avgPtsForMatch'
  5. ,'count(u.id) AS seasons'
  6. ,'sum(s.numOfQue) AS numOfQue'
  7. ,'sum(s.totalPoints) AS totalpoints'
  8. ,'sum(IF(s.position = :win, s.position, 0)) AS wins'
  9. )
  10. ->innerJoin('s.user', 'u')
  11. ->groupBy('u.username')
  12. ->orderBy('avgPtsForMatch', 'DESC')
  13. ->setParameter('win', 1)
  14. ;


i mam następujący błąd:

[Syntax Error] line 0, col 229: Error: Expected known function, got 'IF'





aras785
spórbuj:

  1. SUM(CASE s.position WHEN :win THEN s.position ELSE 0 END) AS wins
lukaskolista
Sugeruję zakończyć tę bezsensowną dyskusję bo:
1. Osoby wypowiadające się w temacie jak widać nie znają DQL oraz nie mają bladego pojęcia o Doctrine (jak widać po ich wypowiedziach)
2. Strzelać w ciemno można bez końca
3. Proponuję nauczyć się czytać komunikaty błędów ze zrozumieniem, bo jest wyraźnie napisane w czym problem.
4. Żadne kombinacje z IFami itp. nie pomogą, bo parser DQL tego nie przeparsuje i tyle.
5. Jak bardzo ten warunek musi tam być, to użyj SQL zamiast DQL lub napisz swoją implementację funkcji SUM do DQL (może ktoś już to zrobił - trzeba sprawdzić).
Pilsener
Uzupełnię wypowiedź poprzednika, polecam:
https://symfony.com/doc/master/bundles/Stof...ndle/index.html

Wycinek z mojego cfg:
Cytat
dql:
string_functions:
MONTH: DoctrineExtensions\Query\Mysql\Month
YEAR: DoctrineExtensions\Query\Mysql\Year


Więcej szczegółów w dokumentacji oczywiście, którą polecam.
Podsumowując, masz następujące opcje:
- native SQL (rezygnacja z DQL)
- napisanie własnej funkcji DQL (które może, ale nie musi działać dokładnie tak samo jak SUM() z MySQL)
- użycie gotowych bibliotek
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.