Kdyby/Doctrine SELECT DISTINCT

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
kiki
Člen | 4
+
0
-

Mam Entitu TestInstance ktera vipada takle

/**
     * @ORM\Entity
     * @ORM\Table(name="test_instance")
     */
    class TestInstance extends BaseEntity {
        /**
         * @var int $idTestInstance
         *
         * @ORM\Id
         * @ORM\Column(type="integer", name="id_testinst")
         * @ORM\GeneratedValue
         */
        protected $idTestInstance;
        /**
         * @var User $user
         *
         * @ORM\ManyToOne(targetEntity="User")
         * @ORM\JoinColumn(name="user_id", referencedColumnName="id_user", nullable=false)
         */
        protected $user;
        /**
         * @var Test $test
         *
         * @ORM\ManyToOne(targetEntity="Test")
         * @ORM\JoinColumn(name="test_id", referencedColumnName="id_test", nullable=false)
         */
        protected $test;
        /**
         * @var boolean $finished
         *
         * @ORM\Column(type="boolean")
         */
        protected $finished;
        /**
         * @var string $startTime
         *
         * @ORM\Column(type="bigint")
         */
        protected $startTime;
        /**
         * @var string $finishTime
         *
         * @ORM\Column(type="bigint", nullable=true)
         */
        protected $finishTime;

        /**
         * @var float $score
         *
         * @ORM\Column(type="float")
         */
        protected $score;

        function __construct() {
            $this->test = new ProxyTest();
            $this->user = new ProxyUser();
        }
       //....

a potrebovala bych vybrat z TestInstance podle usera, a pouze unikatni testy.
(neco jako select distinct test from testInstance where user=$user limit 10 …problem je ze queryBuilder mi nejde pouzit uz vubec)
podarilo se mi jen dostat vsechny bez unikatnich testu

$criteria = Criteria::create()->where(Criteria::expr()->eq('user',$user))->setMaxResults(10);
return $this->testInstances->matching($criteria);

nevite nekdo co s tim prosim?

Editoval kiki (10. 12. 2014 0:16)

Azathoth
Člen | 495
+
0
-

Co přesně znamená unikátní test? Že na něj nemá odkaz nikdo jiný?

kiki
Člen | 4
+
0
-

nn to znamena ze testId je stejny

Editoval kiki (10. 12. 2014 0:03)

Filip Procházka
Moderator | 4668
+
0
-

Napiš normální DQL v query builderu. Pomocí criteria nic takového neuděláš, to umí jen jednoduché filtrování.

Co znamená že ti nejde použít už vůbec? Já si myslím že jde.

kiki
Člen | 4
+
0
-

To sem se asi spatne vyjadrila, sorry. Ja to myslela tak, ze queryBuilder mi pouzit nejde ve smyslu nechapu asi syntaxi jak to napsat. Zkousela sem

$this->testInstances->createQueryBuilder('i')
	 ->select('i.test')
     ->distinct(TRUE)
	 ->where('i.user = :user')
	 ->setParameter('user', $user)
	 ->getQuery()
     ->execute();

a vyhodilo mi to [Semantical Error] line 0, col 18 near ‚test FROM App\Model\TestInstance‘: Error: Invalid PathExpression. Must be a StateFieldPathExpression.
Fakt vubec netusim

Filip Procházka
Moderator | 4668
+
+1
-

DQL nemusíš skládat jenom query builderem, můžeš udělat i

$query = $this->em->createQuery("SELECT a FROM ...");

Pokud to ale chceš QueryBuilderem, tak je vhodné se prva podívat na syntaxi DQL

V examples najdeš například

SELECT DISTINCT u.id FROM CmsArticle a JOIN a.user u

to se zapíše v QB takto

$query = ...->createQueryBuilder()
	->select('DISTINCT u.id')->from('CmsArticle', 'a')
	->join('a.user', 'u')
	->getQuery();

$result = $query->getResult();

musíš si ale uvědomit, že taková query ti už nevrátí entity, ale vrátí ti unikátní idčka nějakých entit, pokud bys udělala

->select('DISTINCT u.id', 'u')

tak ti vrátí IDčka i entity, ale bude to v jiné struktuře, nebude to jenom list entit


Pokud chceš unikátní testy, tak je podle mě daleko lepší selectovat rovnou testy a filtrovat si je podle instancí daného usera.

use Doctrine\ORM\Query\Expr\Join;

$query = $this->tests->createQueryBuilder()
	->select('t')->from(Test::class, 't')
	// nevím jestli je relace oboustraná, takto můžeš udělat join i pokud není
	->innerJoin(TestInstance::class, 'i', Join::WITH, 'i.test = t.id')
	->andWhere('i.user = :user', $user)
	->groupBy('i.id') // tohle možná není potřeba, nevím to z hlavy jistě
	->getQuery();

$result = $query->getResult();
kiki
Člen | 4
+
0
-

Dekuju, ja to uz dokonce vyresila zrovna sama presne takle, takze sem rada ze sem to udelala spravne. :)