Using DISTINCT in a CakePHP find function

僤鯓⒐⒋嵵緔 提交于 2019-11-27 23:38:00

You're right, it seems that you cannot use DISTINCT with list. Since you don't need id but only the names, you can use find all like above and then $first_names = Set::extract($first_names, '/Person/first_name');. That will give you a array with distinct first names.

Try to use 'group by', it works perfectry:

$first_names = $this->Person->find('list', array(
  'fields'=>'first_name',
   'order'=>'Person.first_name ASC',
   'conditions'=> array('Person.status'=>'1'),
   'group' => 'first_name'));

You can try this. Here this takes Person id as key, so there is no chance for duplicate entries.

    $first_names = $this->Person->find('list', array(
    'fields' => array('id','first_name'),
    'conditions' => array('Person.status' => '1'),
   ));
    $this->set('first_names', $first_names);

Here's how I did it in CakePHP 3.x:

     $query = $this->MyTables->find('all');
     $result = $query->distinct()->toArray();

I know it is a question for CakePHP 1.2, but I was searching for that too with CakePHP version 3. And in this version there is a method to form the Query into a distinct one:

$first_names = $this->Persons->find(
    'list',
    [
        'fields'=> ['name']
    ]
)
  ->distinct();
;

This will generate a sql query like this:

SELECT DISTINCT Persons.name AS `Persons__name` FROM persons Persons

But the distinct method is a bit mightier than just inserting DISTINCT in the query.

If you want to just distinct the result on one field, so just throwing away a row with a duplicated name, you can also use the distinct method with an array of the fields as parameter:

$first_names = $this->Persons->find(
    'list',
    [
        'fields'=> ['id', 'name'] //it also works if the field isn't in the selection
    ]
)
  ->distinct(['name']); //when you use more tables in the query, use: 'Persons.name'
;

This will general a sql query like this (for sure it is a group query):

SELECT DISTINCT
    Persons.id AS `Persons__id`, Persons.name AS `Persons__name`
FROM persons Persons
GROUP BY name #respectively Persons.name

Hope I will help some for CakePHP 3. :)

Yes the problem is that you are using a listing which designed for a id / value output. You probably will have to do a find('all') and then build the list yourself.

Yes I also tried to fetch unique results with 'list' but its not working. Then I fixed the problem by using 'all'.

In the example now on the book for version 2 it states the following:

public function some_function() {
    // ...
    $justusernames = $this->Article->User->find('list', array(
        'fields' => array('User.username')
    ));
    $usernameMap = $this->Article->User->find('list', array(
        'fields' => array('User.username', 'User.first_name')
    ));
    $usernameGroups = $this->Article->User->find('list', array(
        'fields' => array('User.username', 'User.first_name', 'User.group')
    ));
    // ...
}

With the above code example, the resultant vars would look something like this:

$justusernames = Array
(
    //[id] => 'username',
    [213] => 'AD7six',
    [25] => '_psychic_',
    [1] => 'PHPNut',
    [2] => 'gwoo',
    [400] => 'jperras',
)

$usernameMap = Array
(
    //[username] => 'firstname',
    ['AD7six'] => 'Andy',
    ['_psychic_'] => 'John',
    ['PHPNut'] => 'Larry',
    ['gwoo'] => 'Gwoo',
    ['jperras'] => 'Joël',
)

$usernameGroups = Array
(
    ['User'] => Array
    (
        ['PHPNut'] => 'Larry',
        ['gwoo'] => 'Gwoo',
    )

    ['Admin'] => Array
    (
        ['_psychic_'] => 'John',
        ['AD7six'] => 'Andy',
        ['jperras'] => 'Joël',
    )

)

You have to plan your query in a slightly different way and plan your database to accommodate a list find.

Using SQL grouping will also produce a distinct list. Not sure of the negative consequences if any, but it seems to work fine for me.

$first_names = $this->Person->find('list', array(
    'fields' => 'first_name',
    'order' => 'first_name',
    'group' => 'first_name',
    'conditions' => array('Person.status' => '1'),
));
$this->set('first_names', $first_names);

In some cases, you wish to group by using some key, but you want unique element within the results. For example, you have a calendar application with two types of events. One event on day 1rst and the other one on the 2nd day of month 1. And you want to show or rather count all the events, grouped by day and by type. If you use only DISTINCT, it is quite difficult. The simplest solution is to group twice:

$this->Events->virtualFields['count'] = 'COUNT(*)';                   
$acts  = $this->Activity->find('all',array(                   
             'group' => array('DAY(Event.start)','EventType.id'),
               ));
Eric Wong

Just group by the fields that you want to get distinct.. or use Set::extract() and then array_unique()

Joshua H

In 2.7-RC version, this is working

$this->Model1->find('list', array(
      'fields' => array('Model1.field1', Model1.field1')
));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!