Как можно получить уникальные значения из таблицы данных с помощью dql?

StackOverflow https://stackoverflow.com/questions/2148620

  •  23-09-2019
  •  | 
  •  

Вопрос

У меня есть таблица, в которой есть столбец, в котором хранятся различные значения.я хочу извлечь уникальные значения из этой таблицы, используя dql.

         Doctrine_Query::create()
                    ->select('rec.school')
                    ->from('Records rec')                   
                    ->where("rec.city='$city' ")                                    
                    ->execute();        

Теперь мне нужны только уникальные значения.Кто-нибудь может сказать мне, как это сделать...

Редактировать

Структура таблицы:

CREATE TABLE IF NOT EXISTS `records` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`state` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `city` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `school` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=16334 ;

Это запрос, который я использую:

   Doctrine_Query::create()
          ->select('DISTINCT rec.city')
          ->from('Records rec')                   
          ->where("rec.state = '$state'")                                    
             // ->getSql();
           ->execute();                 

Генерация Sql для этого дает мне:

SELECT DISTINCT r.id AS r__id, r.city AS r__city FROM records r WHERE r.state = 'AR'

Теперь проверьте сгенерированный sql:::: ОТЧЕТЛИВЫЙ находится в столбце 'id', где, как я хочу, указано в столбце city.Кто-нибудь знает, как это исправить.

РЕДАКТИРОВАТЬ 2

Идентификатор уникален, потому что это автоматически добавляемое значение.Да, у меня есть несколько реальных дубликатов в столбце city, например:Дели и Delhi.Правильно..Теперь, когда я пытаюсь извлечь из него данные, я получаю Delhi два раза.Как я могу сделать запрос, подобный этому:

  select DISTINCT rec.city where state="xyz";

Потому что это даст мне правильный результат.

РЕДАКТИРОВАТЬ 3:

Кто-нибудь, кто может сказать мне, как разобраться в этом запросе ..???

Это было полезно?

Решение

Зависит от того, какую версию вы используете, но у меня была такая же проблема, и ->distinct() сработала у меня.

Doctrine_Query::create()
      ->select('rec.city')->distinct()
      ->from('Records rec')                   
      ->where("rec.state = '$state'")                                    
       ->execute();     

Другие советы

Не могли бы вы использовать ГРУППУ BY?

Doctrine_Query::create()
    ->select('rec.school')
    ->from('Records rec')                   
    ->where("rec.city='$city' ")                                    
    ->groupBy('rec.school')   
    ->execute();

В RawSql нет необходимости
Вместо ->выбрать('DISTINCT rec.city')
Использовать -> выбрать('ОТЛИЧИТЬ (rec.city) как город')

Вы можете использовать Raw_Sql ( исходный код ) класс для достижения этой цели.Вот тест, который я только что провел на своей собственной базе данных:

<?php

set_include_path(get_include_path() . PATH_SEPARATOR . 'library');

require('Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));

Doctrine::loadModels('application/models/generated');
Doctrine::loadModels('application/models');

$dm=Doctrine_Manager::getInstance();
$conn = $dm->openConnection("mysql://dbuser:dbpass@localhost/database");  //changed actual values...
$q = new Doctrine_RawSql($conn);

$q->select('{c.name}')
   ->distinct()
   ->from('contactlist c')
   ->addComponent('c', 'Contactlist');

//this outputs:  SELECT DISTINCT c.name AS c__name FROM contactlist c
echo $q->getSqlQuery() . "<br>\n"; 

$contacts = $q->execute();
foreach($contacts->toArray() as $contact){
    echo $contact['name'] . "<br>\n";
}

?>

DISTINCT - это агрегирующая функция.Как таковая Доктрина не может преобразовать ваш результат в объекты.Используйте другую стратегию увлажнения, как предложил бартман.

$q = Doctrine_Query::create()
->select('DISTINCT rec.city')
->from('Records rec')
->execute(array(), Doctrine_Core::HYDRATE_SCALAR);

у меня все работало нормально

Причина, по которой Doctrine всегда добавляет первичный ключ в список полей, лежит внутри Гидратации.Когда Doctrine извлекает строки из базы данных, она гидратирует (= преобразует) их в иерархию объектов и ссылается на объекты модели, используя первичный ключ.В вашем случае такое поведение нежелательно, поскольку представляют интерес только названия городов.

Я предлагаю два решения, к сожалению, я не могу протестировать их прямо сейчас.

  1. Попробуйте использовать Doctrine_RawSql Доктрина_RawSql.RawSql имеет специальную обработку для РАЗНЫХ запросов.

$q = Doctrine_RawSql::create()
->select('DISTINCT {rec.city}')
->from('Records rec')
->where('rec.state = ?', $state) ->addComponent('rec', 'Record');

$cities = $q->execute()

  1. Используйте гидратор, не основанный на иерархии объектов.Это может помешать Doctrine извлечь поле первичного ключа для инициализации класса модели.Смотрите документацию (не могу опубликовать ссылку - новый пользователь.извините.) для получения дополнительной информации.

$q = Doctrine_Query::create()
->select('DISTINCT rec.city')
->from('Records rec')
->where("rec.state = ?", $state);

$cities = $q->execute(array(), Doctrine_Core::HYDRATE_SCALAR);

$cities должны содержать массив массивов с ключами типа 'rec_city'.

Пожалуйста, обратите внимание на использование ? заполнитель в операторах where рекомендуется позволять Doctrine выполнять экранирование и не бороться с этим самостоятельно.

$query = $this->getEntityManager()->createQueryBuilder()
                    ->select('DISTINCT(p.document)')
                    ->from('Products', 'p');

Это работает для меня.

Повторно отвеченный:

Проверил это на моем локальном компьютере - не сработало.Поэтому позвольте мне посоветовать использовать PDO до тех пор, пока это не будет улучшено или исправлено:

$dbh = Doctrine_Manager::connection()->getDbh();
$stmt = $dbh->prepare('SELECT DISTINCT(rec.city) FROM <tablename> WHERE rec.state = :state');
$stmt->bindParam(':state', $state);
$stmt->execute();
$result = $stmt->fetchAll();

Совет
Я бы порекомендовал вам использовать внешний ключ ссылка на список городов на city столбец вместо обычного текста для гибкости и повышения производительности.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top