¿Cómo db_select DISTINCT en un campo en particular en Drupal 7?


7

Entiendo que puede especificar -> distinct () en la instrucción db_select para que solo devuelva valores distintos al mirar TODOS los campos. Pero lo que quiero es devolver valores distintos solo mirando UN campo. Aquí está mi código:

$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');

Supongamos que quiero que la columna distinta sea e.nid. Pensaría que -> distinct ('e.nid') funcionaría pero aún así devuelve valores distintos basados ​​en todos los campos (es decir, distintos (columnas1, columna2, columna3, etc.).


1
¿Alguna posibilidad de que pueda dar una muestra del SQL de salida que está buscando? Eso haría que sea bastante fácil descubrir cómo convencerlo db_selectpara que haga lo mismo
Clive

Respuestas:


12

Suponiendo que está tratando de llegar aproximadamente a esta consulta:

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

Usarías:

$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');

Esto me da todos los campos distintos, no solo nid ser distinto
CHRIS

No estoy seguro de lo que quieres decir, lo anterior es una consulta distinta ... ¿qué SQL estás tratando de producir?
Clive

1
supongamos que hay '4' '4' '5' '5' en la columna nid con una columna correspondiente llamada 'tipo' con 'a' 'b' 'c' 'd'. bueno, si selecciono distinto en ambas columnas (nid, tipo), el resultado tendrá 4 filas. pero si selecciono distinto en SOLO nid, el resultado tendrá 2 filas. Estoy tratando de seleccionar distinto en SOLO nid
CHRIS

2
Creo que está malinterpretando cómo funciona la agrupación en SQL ... para hacer lo que está describiendo necesitaría eliminar la columna de tipo de los campos seleccionados
Clive

7

DISTINCT es en realidad un post-modificador global para SELECT, es decir, a diferencia de SELECT ALL (que devuelve todas las respuestas) es SELECT DISTINCT (que devuelve todas las respuestas únicas). Entonces, un solo DISTINCT actúa en TODAS las columnas que le das.

Esto hace que sea muy difícil usar DISTINCT en una sola columna, mientras se obtienen las otras columnas, sin hacer grandes volteretas extremadamente feas.

La respuesta correcta es usar un GROUP BY en las columnas que desea tener respuestas únicas:


Exactamente. Es por eso que DBTNG lo tiene en el nivel de consulta. El único momento en que DISTINCT está a nivel de columna (o vagamente lo parece) es cuando lo hace, COUNT(DISTINCT foo)pero incluso así es un modificador de la función del agregador.

2

Retirar ->distinct()y reemplazar con$event_table->AddExpression('distinct e.nid', 'nid');

Al igual que:

$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');

PDOException: SQLSTATE [42000]: Error de sintaxis o infracción de acceso: 1064 Tiene un error en la sintaxis de SQL; consulte el manual que corresponde a la versión de su servidor MySQL para obtener la sintaxis correcta para usar cerca de 'distintivo e.nid AS nid DESDE mcc_notify_event_queue e INNER JOIN nodo n ON e.nid' en la línea 1: SELECCIONE e. , n. estado AS estado, n. título Título AS, e.nid distinto AS anid DESDE {mcc_notify_event_queue} e INNER JOIN {nodo} n ON e.nid = n.nid GRUPO POR e.time ORDEN POR e.time ASC; Array ()
CHRIS

no puede usar e. * y e.nid distinto, arroja un error. Tendrá que escribir sus campos como he señalado anteriormente.
Scott Joudry

Todavía recibo un error. Todo lo que he hecho es cambiar su código a $ event_table-> fields ('e', array ('nid', 'time', 'event_type')) // SELECCIONE los campos de los eventos
CHRIS

todavía está seleccionando nid dos veces en ese caso, lo que explica el error. Pruebe $ event_table-> fields ('e', array ('time', 'event_type'))
Scott Joudry

sigue siendo un error distinto e.nid AS nid FROM my_module_event_queue e INNER JOIN nodo n ON e.nid 'en la línea 1: SELECCIONE e.time AS time, e.event_type AS event_type, n.type AS type, n.status AS status, n.título AS título, distinto e.nid AS nid DESDE {my_module_event_queue} e INNER JOIN {node} n ON e.nid = n.nid GROUP BY e.time ORDER BY e.time ASC;
CHRIS

-1

Si usa esta consulta, entonces proporcionará una consulta distinta adecuada.

<?php  

$select = db_select('service_payment_transaction','o');
$select->distinct('o.transaction_id');
$select->innerJoin('users', 'u', 'u.uid = o.user_id');
$select->fields('o');
$select->fields('u');
$select->condition('o.service_gv_code','','!=');
$select->range($start,$page_count);
$select->groupBy('o.service_gv_code');
$select->orderBy('transaction_id', 'DESC');
$result_query = $select->execute();

1
La función distinta toma un booleano como argumento, no una cadena.
Felix Eve el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.