Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [SF2][Symfony2][Symfony] setParameter nie działa w SELECT RepositoryClass
damianooo
post
Post #1





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


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ć ?

Ten post edytował damianooo 7.09.2016, 12:14:56
Go to the top of the page
+Quote Post
lukaskolista
post
Post #2





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


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.

Ten post edytował lukaskolista 7.09.2016, 12:04:52
Go to the top of the page
+Quote Post
damianooo
post
Post #3





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


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ć ?
Go to the top of the page
+Quote Post
lukaskolista
post
Post #4





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


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ę.

Ten post edytował lukaskolista 7.09.2016, 14:40:39
Go to the top of the page
+Quote Post
damianooo
post
Post #5





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


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 ?
Go to the top of the page
+Quote Post
Gothicbezimienny
post
Post #6





Grupa: Zarejestrowani
Postów: 66
Pomógł: 0
Dołączył: 5.11.2014

Ostrzeżenie: (0%)
-----


skoro to liczba to może spróbuj :

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


  1. ->setParameter(1, 1)


Ten post edytował Gothicbezimienny 8.09.2016, 09:14:36
Go to the top of the page
+Quote Post
damianooo
post
Post #7





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


nie działa niestety (IMG:style_emoticons/default/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'


Ten post edytował damianooo 8.09.2016, 09:24:31
Go to the top of the page
+Quote Post
Gothicbezimienny
post
Post #8





Grupa: Zarejestrowani
Postów: 66
Pomógł: 0
Dołączył: 5.11.2014

Ostrzeżenie: (0%)
-----


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();


Ten post edytował Gothicbezimienny 8.09.2016, 09:39:54
Go to the top of the page
+Quote Post
damianooo
post
Post #9





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


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. }
Go to the top of the page
+Quote Post
Gothicbezimienny
post
Post #10





Grupa: Zarejestrowani
Postów: 66
Pomógł: 0
Dołączył: 5.11.2014

Ostrzeżenie: (0%)
-----


nadal brakuje FROM

$repository = $this->getDoctrine()
->getRepository('AppBundle:statistics ');


Ten post edytował Gothicbezimienny 8.09.2016, 09:42:09
Go to the top of the page
+Quote Post
damianooo
post
Post #11





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


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();


Ten post edytował damianooo 8.09.2016, 10:03:18
Go to the top of the page
+Quote Post
Gothicbezimienny
post
Post #12





Grupa: Zarejestrowani
Postów: 66
Pomógł: 0
Dołączył: 5.11.2014

Ostrzeżenie: (0%)
-----


Nie mogłem tego wiedzieć ze masz to gdzieś.
Go to the top of the page
+Quote Post
damianooo
post
Post #13





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/sad.gif)

Ten post edytował damianooo 8.09.2016, 10:09:28
Go to the top of the page
+Quote Post
Turson
post
Post #14





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

Ostrzeżenie: (0%)
-----


Spróbuj zamiast 's.position = 1' wstawić tam podzapytanie
Go to the top of the page
+Quote Post
aras785
post
Post #15





Grupa: Zarejestrowani
Postów: 859
Pomógł: 177
Dołączył: 29.10.2009

Ostrzeżenie: (0%)
-----


  1. SUM(IF(s.position = :win, s.position, 0)) AS wins
Go to the top of the page
+Quote Post
damianooo
post
Post #16





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


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'





Go to the top of the page
+Quote Post
aras785
post
Post #17





Grupa: Zarejestrowani
Postów: 859
Pomógł: 177
Dołączył: 29.10.2009

Ostrzeżenie: (0%)
-----


spórbuj:

  1. SUM(CASE s.position WHEN :win THEN s.position ELSE 0 END) AS wins
Go to the top of the page
+Quote Post
lukaskolista
post
Post #18





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


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ć).

Ten post edytował lukaskolista 8.09.2016, 18:17:19
Go to the top of the page
+Quote Post
Pilsener
post
Post #19





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 4.09.2025 - 02:25