Извлекайте отдельные строки без удвоенных значений свойств в MySql DB с помощью Symfony 3.4 и Doctrine - PullRequest
0 голосов
/ 23 октября 2018

В приложении Symfony 3.4 у меня есть сущность с 4 свойствами и идентификатором.

Он управляется доктриной в базе данных mySql.

Произнесите свойства с именами p1, p2,p3 и q.Пример таблицы БД может выглядеть следующим образом:

id  p1  p2  p3  q
------------------
1   x   y   z   1
2   x   y   n   2
3   x       z   1
4   x       z   2
5   x   y   z   3
6   x   y   z   4
7   x   n   z   1

Что мне нужно сделать, это запросить все сущности из БД, которые имеют различные комбинации p1, p2, p3.Таким образом, используя приведенную примерную таблицу БД, результат, который мне нужен, будет

id  p1  p2  p3  q
------------------
1   x   y   z   1
2   x   y   n   2
3   x       z   1
7   x   n   z   1

Таким образом, строки с идентификаторами 4, 5 и 6 не будут в наборе, потому что у них есть «удвоенные» комбинации p1, p2, p3.

Теперь - как мне это сделать, используя методы класса репозитория Symfony 3.4, как описано здесь:

https://symfony.com/doc/3.4/doctrine.html

Или есть какие-либо другиеспособы достижения того, что я ищу?

Любые советы приветствуются.

РЕДАКТИРОВАТЬ: В основном я ищу список всех существующих комбинаций p1, p2, p3 без комбинации, удвоенной в списке.Неважно, какая строка возвращается в наборе результатов (относительно свойств id и q), если включена одна (и только одна) строка каждой комбинации p1, p2, p3.

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Если вам нужна только уникальная комбинация p1, p2 и p3 и вас не волнуют id и q, вы можете исключить их из запроса и использовать отдельное предложение.

Для вашей потребности не существует встроенного метода класса Repository. Возможно, вы захотите создать пользовательский класс репозитория (лично я делаю это каждый раз, когда мне приходится писать собственные запросы длямои сущности)

Давайте рассмотрим вашу сущность (расположенную в примере в src/AppBundle/Entity/MyEntity.php), объявленную так:

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\MyEntityRepository")
 */
class MyEntity
{
    //declarations of $id, $p1 and so on...
}

Вы можете создать собственный класс хранилища (в примере src/AppBundle/Repository/MyEntityRepository.php) сметод для получения необходимого результата:

namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;

class MyEntityRepository extends EntityRepository
{
    public function findAllUniqueCombinations()
    {
        $result = $this->createQueryBuilder('m')
                       ->select('m.p1 p1', 'm.p2 p2', 'm.p3 p3')
                       ->distinct()
                       ->getQuery()
                       ->getResult();

        return ($result);
    }
}

И, в некоторых действиях контроллера:

$MyCombinationList = $this->getDoctrine()
                          ->getManager()
                          ->getRepository(MyEntity::class)
                          ->findAllUniqueCombinations();

Я использовал для тестирования тот же самый запрос (только select()изменено)

Входные данные

id | name       | firstname
---+------------+---------- 
 1 | Smith      | John 
 2 | Smith      | John 
 3 | Smith      | John 
 4 | Smith      | John 
 5 | Doe        | Jane 
 6 | Connor     | Sarah 
 7 | The Sponge | Bob 
 8 | Marley     | Bob

Выбор был ->select('c.name name', 'c.firstname firstname')

Выход var_dump($result); дал:

array (size=5)
  0 => 
    array (size=2)
      'name' => string 'Smith' (length=5)
      'firstname' => string 'John' (length=4)
  1 => 
    array (size=2)
      'name' => string 'Doe' (length=3)
      'firstname' => string 'Jane' (length=4)
  2 => 
    array (size=2)
      'name' => string 'Connor' (length=6)
      'firstname' => string 'Sarah' (length=5)
  3 => 
    array (size=2)
      'name' => string 'The Sponge' (length=9)
      'firstname' => string 'Bob' (length=3)
  4 => 
    array (size=2)
      'name' => string 'Marley' (length=6)
      'firstname' => string 'Bob' (length=3)
0 голосов
/ 23 октября 2018

Подзапрос «group by» для удаления дублированных данных и основной запрос для поиска по идентификаторам:

$dql = 'SELECT r FROM myTable r
WHERE r.id IN (
    SELECT min(s.id) FROM myTable s
    GROUP BY s.p1, s.p2, s.p3
)';

$rows = $em->createQuery($dql)
    ->getResult();
...