web-dev-qa-db-fra.com

Comment db_select DISTINCT sur un champ particulier dans Drupal 7?

Je comprends que vous pouvez spécifier -> distinct () sur l'instruction db_select afin qu'elle ne renvoie que des valeurs distinctes lorsque vous regardez TOUS les champs. Mais ce que je veux, c'est retourner des valeurs distinctes en ne regardant qu'un seul champ. Voici mon code:

$event_table = db_select('my_table', 'e')
    ->distinct()
    ->orderBy('e.time', 'ASC');//ORDER BY
$event_table->join('node', 'n', 'e.nid = n.nid'); //JOIN node with events
$event_table->groupBy('e.time');//GROUP BY time
$event_table->fields('e')//SELECT the fields from events
    ->fields('n',array('type','status','title'))//SELECT the fields from node
    ->orderBy('e.time', 'ASC');//ORDER BY

$result_event_table = $event_table->execute();
$result_event_table = $result_event_table->fetchAllAssoc('time');

Supposons que je veuille que la colonne distincte soit e.nid. On pourrait penser que -> distinct ('e.nid') fonctionnerait mais il renvoie toujours des valeurs distinctes basées sur tous les champs (c'est-à-dire distinct (colonnes1, colonne2, colonne3, etc.).

7
CHRIS

En supposant que vous essayez d'accéder à peu près à cette requête:

SELECT DISTINCT e.nid AS nid, e.time AS time, n.type AS type, n.status AS status, n.title AS title
FROM 
{my_table} e
INNER JOIN {node} n ON n.nid = e.nid
GROUP BY e.time
ORDER BY e.time ASC

Vous utiliseriez:

$query = db_select('my_table', 'e')
  ->distinct()
  ->fields('e', array('nid', 'time', 'foo', 'bar'))
  ->fields('n', array('type', 'status', 'title'))
  ->groupBy('e.time')
  ->orderBy('e.time');

$query->join('node', 'n', 'n.nid = e.nid');
12
Clive

DISTINCT est en fait un post-modificateur global pour SELECT, c'est-à-dire que contrairement à SELECT ALL (renvoyant toutes les réponses), c'est SELECT DISTINCT (renvoyant toutes les réponses uniques). Un seul DISTINCT agit donc sur TOUTES les colonnes que vous lui donnez.

Cela rend très difficile l'utilisation de DISTINCT sur une seule colonne, tout en obtenant les autres colonnes, sans effectuer de backflips extrêmement moche.

La bonne réponse consiste à utiliser un GROUP BY sur les colonnes pour lesquelles vous souhaitez avoir des réponses uniques:

7
TBI Infotech

Supprimez ->distinct() et remplacez-le par $event_table->AddExpression('distinct e.nid', 'nid');

Ainsi:

$event_table = db_select('my_table', 'e');
$event_table->AddExpression('distinct e.nid', 'nid')
$event_table->orderBy('e.time', 'ASC');//ORDER BY
$event_table->join('node', 'n', 'e.nid = n.nid'); //JOIN node with events
$event_table->groupBy('e.time');//GROUP BY time

// you need to outline all fields here, can't use e.*
$event_table->fields('e')//SELECT the fields from events

    ->fields('n',array('type','status','title'))//SELECT the fields from node
    ->orderBy('e.time', 'ASC');//ORDER BY

$result_event_table = $event_table->execute();
$result_event_table = $result_event_table->fetchAllAssoc('time');
2
Scott Joudry