Як вибрати окремий запит за допомогою конструктора запитів доктрини symfony2?


76

У мене є цей код symfony, де він отримує всі категорії, пов’язані з розділом блогу мого проекту:

$category = $catrep->createQueryBuilder('cc')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->getQuery();

$categories = $category->getResult();

Це працює, але запит містить дублікати:

Test Content
Business
Test Content

Я хочу використовувати DISTINCTкоманду у своєму запиті. Єдині приклади, які я бачив, вимагають від мене написання необробленого SQL. Я хочу уникнути цього, наскільки це можливо, оскільки я намагаюся залишити весь код незмінним, щоб усі вони використовували функцію QueryBuilder, надану Symfony2 / Doctrine.

Я спробував додати distinct()до свого запиту так:

$category = $catrep->createQueryBuilder('cc')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->distinct('cc.categoryid')
    ->getQuery();

$categories = $category->getResult();

Але це призводить до наступної помилки:

Фатальна помилка: виклик невизначеного методу Doctrine \ ORM \ QueryBuilder :: distinct ()

Як сказати symfony вибрати відмінний?


2
Ви повинні передати логічне значення функції distinct (). doctrine-project.org/api/orm/2.2/…
Омн,

Відповіді:


31

ви могли б написати

select DISTINCT f from t;

як

select f from t group by f;

Справа в тому, що я зараз переймаюся вченням, тому я не можу дати вам реальної відповіді. але ви могли, як показано вище, змоделювати окрему групу за допомогою і перетворити це на Доктрину . якщо ви хочете додати додаткову фільтрацію, використовуйте HAVINGпісля групування за.


1
@mickburkejnr Поки ви не додасте пропозицію ORDER. :(
undefined

1
@xyu Я знаю, це не ідеально, правда? Чому ми повинні мати щось подібне? Чому це не може просто спрацювати?
mickburkejnr

1
Групування @mickburkejnr відбувається перед замовленням в SQL.
undefined

11
Це правильна відповідь, якщо ви використовуєте оператор sql, а не конструктор запитів. Це не повинно бути позначено, оскільки відповідь, яку дав @skler, є правильною.
Tom T

2
(Старий коментар, я знаю ...). @Tom T: Насправді ця відповідь вірна. Це означає, що замість того, щоб намагатися використовувати власне DISTINCT ключове слово, GROUP BYзмоделюйте його, використовуючи QueryBuilder. Однак він не зміг навести приклад. Ось простий:$q = $db->createQueryBuilder(); $q->select('f')->from('t', 't')->groupBy('f');
user128216

173

Це працює:

$category = $catrep->createQueryBuilder('cc')
        ->select('cc.categoryid')
        ->where('cc.contenttype = :type')
        ->setParameter('type', 'blogarticle')
        ->distinct()
        ->getQuery();

$categories = $category->getResult();

Редагувати для Symfony 3 і 4.

Вам слід використовувати ->groupBy('cc.categoryid')замість->distinct()


54

Якщо ви використовуєте оператор "select ()", ви можете зробити це:

$category = $catrep->createQueryBuilder('cc')
    ->select('DISTINCT cc.contenttype')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->getQuery();

$categories = $category->getResult();

-1

Просто відкрийте файл сховища та додайте цю нову функцію, а потім зателефонуйте їй всередину контролера:

 public function distinctCategories(){
        return $this->createQueryBuilder('cc')
        ->where('cc.contenttype = :type')
        ->setParameter('type', 'blogarticle')
        ->groupBy('cc.blogarticle')
        ->getQuery()
        ->getResult()
        ;
    }

Тоді у вашому контролері:

public function index(YourRepository $repo)
{
    $distinctCategories = $repo->distinctCategories();


    return $this->render('your_twig_file.html.twig', [
        'distinctCategories' => $distinctCategories
    ]);
}

Удачі!


Що ви маєте на увазі під словом "ніхто не працював"? Що відбувається замість цього? Чому це має бути проблемою Symfony, тоді як конструктор запитів є частиною Doctrine?
Ніко Хаасе,

@NicoHaase, оскільки створення нового проекту Symfony за допомогою композитора встановить найновішу версію Twig and Doctrine, саме тому я згадав, що моє рішення тестується на Symfony5 і будь-яка версія Doctrine поставляється з ним. Сподіваюся, зараз це зрозуміліше.
Алі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.