如何在Drupal 7中的特定字段上db_select DISTINCT?


7

我了解您可以在db_select语句上指定-> distinct(),以便在查看所有字段时仅返回不同的值。但是我想要的是通过仅查看一个字段来返回不同的值。这是我的代码:

$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。您可能会认为-> distinct('e.nid')可以工作,但是它仍会基于所有字段返回不同的值(即,distinct(columns1,column2,columns3等)。


1
您是否有机会提供所要查找的输出SQL示例?这样可以很容易地弄清楚如何哄骗他们db_select做同样的事情
克莱夫(Clive)

Answers:


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是不同的
CHRIS

我不确定您的意思,上面是一个独特的查询...您尝试生成什么SQL?
克莱夫(Clive)

1
假设在nid列中有“ 4”,“ 4”,“ 5”,“ 5”,其对应的列名为“ type”,且具有“ a”,“ b”,“ c”,“ d”。好吧,如果我在两列(nid,type)上都选择了distinct,那么结果将有4行。但是,如果我仅选择nid,结果将有2行。我正在尝试在Just nid上选择与众不同
CHRIS

2
我想你是误会了如何在分组SQL作品......做你描述你需要从选定字段删除类型列
克莱夫

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服务器版本对应的手册以获取正确的语法,以在第1行“ SELECT e。*,n.type AS类型”附近在“ distinct e.nid AS nid FROM mcc_notify_event_queue e INNER JOIN节点n ON e.nid”附近使用,n.status AS状态,n.title AS标题,不同的e.nid AS辅助信息来自{mcc_notify_event_queue} e INNER JOIN {node} n ON e.nid = n.nid GROUP BY e.time ORDER BY e.time ASC;Array()
CHRIS

不能使用e。*和不同的e.nid,会引发错误。如上所述,您需要填写您的字段。
Scott Joudry

我仍然遇到错误。我要做的就是将代码更改为$ event_table-> fields('e',array('nid','time','event_type'))//从事件中选择字段
CHRIS

在这种情况下,您仍然要选择两次nid,这可以解释该错误。试试$ event_table-> fields('e',array('time','event_type'))
Scott

e.nid AS仍然是错误,但my.module_event_queue e INNER JOIN节点n ON e.nid'在第1行:选择e.time AS时间,e.event_type AS event_type,n.type AS类型,n.status AS状态, n.title AS标题,不同的e.nid AS nid,来自{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

如果您使用此查询,则它提供适当的独特查询。

<?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
不同的功能需要一个布尔值,因为它的参数,而不是字符串。
菲利克斯·夏娃
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.