Wie kann ich DISTINCT für ein bestimmtes Feld in Drupal 7 auswählen?

7

Ich verstehe, dass Sie in der Anweisung db_select -> unique () angeben können, damit nur beim Betrachten ALLER Felder unterschiedliche Werte zurückgegeben werden. Ich möchte jedoch unterschiedliche Werte zurückgeben, indem ich nur EIN Feld betrachte. Hier ist mein 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');

Angenommen, ich möchte, dass die eindeutige Spalte e.nid ist. Sie würden denken, dass -> different ('e.nid') funktionieren würde, aber es werden immer noch unterschiedliche Werte basierend auf allen Feldern zurückgegeben (dh different (Spalten1, Spalte2, Spalte3 usw.).

CHRIS
quelle
1
Gibt es eine Chance, ein Beispiel für das von Ihnen gesuchte Ausgabe-SQL zu geben? Das würde es ziemlich einfach machen, herauszufinden, wie man dazu überredet db_select, dasselbe zu tun
Clive

Antworten:

12

Angenommen, Sie versuchen, ungefähr zu dieser Abfrage zu gelangen:

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

Sie würden verwenden:

$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');
Clive
quelle
Dies gibt mir nur alle Felder verschieden, nicht nur verschieden
CHRIS
Ich bin nicht sicher, was Sie meinen, das obige ist eine eindeutige Abfrage ... welches SQL versuchen Sie zu produzieren?
Clive
1
Angenommen, in der nid-Spalte befindet sich '4' '4' '5' '5' mit einer entsprechenden Spalte namens 'type' mit 'a' 'b' 'c' 'd'. Nun, wenn ich in beiden Spalten (nid, type) einen unterschiedlichen Wert auswähle, hat das Ergebnis 4 Zeilen. aber wenn ich auf NUR nid unterscheidend wähle, hat das Ergebnis 2 Zeilen. Ich versuche, auf
NUR
2
Ich denke, Sie verstehen falsch, wie das Gruppieren in SQL funktioniert. Um das zu tun, was Sie beschreiben, müssen Sie die Typenspalte aus den ausgewählten Feldern entfernen
Clive
7

DISTINCT ist eigentlich ein globaler Post-Modifikator für SELECT, dh im Gegensatz zu SELECT ALL (Rückgabe aller Antworten) ist es SELECT DISTINCT (Rückgabe aller eindeutigen Antworten). Ein einzelnes DISTINCT wirkt also auf ALLE Spalten, die Sie ihm geben.

Dies macht es wirklich schwierig, DISTINCT für eine einzelne Spalte zu verwenden, während die anderen Spalten abgerufen werden, ohne größere, extrem hässliche Backflips auszuführen.

Die richtige Antwort besteht darin, ein GROUP BY für die Spalten zu verwenden, für die Sie eindeutige Antworten erhalten möchten:

TBI Infotech
quelle
Genau. Deshalb hat DBTNG es auf Abfrageebene. DISTINCT ist nur dann auf Spaltenebene (oder sieht vage so aus), wenn Sie dies tun, COUNT(DISTINCT foo)aber selbst dann ist es ein Modifikator der Aggregatorfunktion.
2

Entfernen ->distinct()und ersetzen Sie es durch$event_table->AddExpression('distinct e.nid', 'nid');

Wie so:

$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');
Scott Joudry
quelle
PDOException: SQLSTATE [42000]: Syntaxfehler oder Zugriffsverletzung: 1064 Sie haben einen Fehler in Ihrer SQL-Syntax. Überprüfen Sie das Handbuch, das Ihrer MySQL-Serverversion entspricht, auf die richtige Syntax für die Verwendung in der Nähe von 'eindeutiger e.nid AS nid FROM mcc_notify_event_queue e INNER JOIN-Knoten n ON e.nid' in Zeile 1: SELECT e. *, n.type AS-Typ , n.status AS-Status, n.title AS-Titel, eindeutige e.nid AS-Anid FROM {mcc_notify_event_queue} e INNER JOIN {Knoten} n ON e.nid = n.nid GRUPPE NACH e.time ORDER BY e.time ASC; Array ()
CHRIS
kann e. * nicht verwenden und unterscheidet e.nid, löst einen Fehler aus. Sie müssen Ihre Felder wie oben beschrieben ausschreiben.
Scott Joudry
Ich erhalte immer noch einen Fehler. Alles, was ich getan habe, ist, Ihren Code in $ event_table-> fields ('e', array ('nid', 'time', 'event_type') zu ändern. // SELECT the fields from events
CHRIS
In diesem Fall wählen Sie immer noch zweimal nid aus, was den Fehler erklärt. Versuchen Sie $ event_table-> fields ('e', array ('time', 'event_type'))
Scott Joudry
immer noch ein Fehler verschieden e.nid AS nid FROM my_module_event_queue e INNER JOIN Knoten n ON e.nid 'in Zeile 1: SELECT e.time AS Zeit, e.event_type AS event_type, n.type AS Typ, n.status AS Status, n.title AS-Titel, eindeutige e.nid AS nid FROM {my_module_event_queue} e INNER JOIN {Knoten} n ON e.nid = n.nid GROUP BY e.time ORDER BY e.time ASC;
CHRIS
-1

Wenn Sie diese Abfrage dann verwenden, bietet sie eine ordnungsgemäße eindeutige Abfrage.

<?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();
Priyank
quelle
1
Die eindeutige Funktion verwendet einen Booleschen Wert als Argument, keinen String.
Felix Eve