Как db_select DISTINCT для определенного поля в Drupal 7?


7

Я понимаю, что вы можете указать -> Different () в операторе db_select, чтобы он возвращал только разные значения при просмотре ВСЕХ полей. Но то, что я хочу, это чтобы вернуть отдельные значения, только глядя на одно поле. Вот мой код:

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

Предположим, я хочу, чтобы отдельный столбец был e.nid. Вы могли бы подумать, что -> Different ('e.nid') будет работать, но он по-прежнему возвращает разные значения, основанные на всех полях (то есть, отличные (columns1, column2, column3 и т.д.).


1
Есть ли шанс, что вы могли бы привести пример выходного SQL, который вы ищете? Это позволило бы довольно легко понять, как уговорить db_selectсделать то же самое
Клайв

Ответы:


12

Предполагая, что вы пытаетесь получить примерно до этого запроса:

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

Вы бы использовали:

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

Это просто дает мне все поля различны, а не просто
NID

Я не уверен, что вы имеете в виду, выше приведен отдельный запрос ... какой SQL вы пытаетесь создать?
Клайв

1
предположим, что в столбце nid есть '4' '4' '5' '5' с соответствующим столбцом с именем 'type' с 'a' 'b' 'c' 'd'. хорошо, если я выберу отличные в обоих столбцах (nid, type), результат будет иметь 4 строки. но если я выберу отличное на просто NID, результат будет иметь 2 строки. Я пытаюсь выбрать отличительные только на нид
Крис

2
Я думаю, вы не понимаете, как группировка работает в SQL ... чтобы сделать то, что вы описываете, вам нужно удалить столбец типа из выбранных полей
Clive

7

DISTINCT на самом деле является глобальным пост-модификатором для SELECT, то есть, в отличие от SELECT ALL (возвращает все ответы), это SELECT DISTINCT (возвращает все уникальные ответы). Таким образом, один DISTINCT действует на ВСЕ столбцы, которые вы ему даете.

Это делает очень трудным использование DISTINCT для одного столбца, в то время как другие столбцы получаются без каких-либо серьезных уродливых сальто.

Правильный ответ - использовать GROUP BY для столбцов, для которых вы хотите получить уникальные ответы:


Точно. Вот почему DBTNG имеет его на уровне запросов. Единственный раз, когда DISTINCT - это уровень столбца (или выглядит смутно), это когда вы это делаете, COUNT(DISTINCT foo)но даже тогда это модификатор функции-агрегатора.

2

Удалить ->distinct()и заменить его$event_table->AddExpression('distinct e.nid', 'nid');

Вот так:

$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]: синтаксическая ошибка или нарушение прав доступа: 1064 В синтаксисе SQL есть ошибка; обратитесь к руководству, соответствующему вашей версии сервера MySQL, чтобы узнать правильный синтаксис для использования рядом с 'отдельным e.nid AS nid FROM mcc_notify_event_queue e Узел INNER JOIN n ON e.nid' в строке 1: SELECT e. *, n.type AS type , статус n.status AS, заголовок n.title AS, отдельный e.nid AS и помощь FROM {mcc_notify_event_queue} e INNER JOIN {узел} n ON e.nid = n.nid GROUP BY e.time ORDER BY e.time ASC; Array ()
CHRIS

не может использовать e. * и отличный e.nid, выдает ошибку. Вам нужно будет выписать свои поля, как я уже отмечал выше.
Скотт Джудри

Я все еще получаю ошибку. Все, что я сделал, это изменил ваш код на $ event_table-> fields ('e', array ('nid', 'time', 'event_type')) // ВЫБОР полей из событий
CHRIS

в этом случае вы все еще выбираете nid дважды, что объясняет ошибку. Попробуйте $ event_table-> fields ('e', array ('time', 'event_type'))
Скотт Джудри

по-прежнему ошибка, отличная e.nid AS nid ОТ my_module_event_queue e Узел INNER JOIN n ON e.nid 'в строке 1: ВЫБРАТЬ время AS e.time, тип AS e.event_type, тип AS n.type, состояние AS n.status, n.title AS title, отдельный e.nid AS nid FROM {my_module_event_queue} e INNER JOIN {узел} n ON e.nid = n.nid GROUP BY e.time ORDER BY e.time ASC;
Крис

-1

Если вы используете этот запрос, то предоставьте правильный отдельный запрос.

<?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
Отчетливая функция принимает логическое значение , как это аргумент, а не строка.
Феликс Ив
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.