Drupal 7の特定のフィールドでDISTINCTをdb_selectする方法は?


7

すべてのフィールドを調べたときに明確な値のみが返されるように、db_selectステートメントで-> distinct()を指定できることを理解しています。しかし、私が望んでいるのは、1つのフィールドだけを見て、明確な値を返すことです。これが私のコードです:

$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、column3など)。


1
探している出力SQLのサンプルを提供できる可能性はありますか?そうすればdb_select、同じことを行うように調整する方法を簡単に理解できるようになります
Clive

回答:


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を作成しようとしているのですか?
クライブ

1
nid列に「4」「4」「5」「5」があり、「type」という名前の対応する列に「a」「b」「c」「d」が付いているとします。まあ、両方の列(nid、type)で個別を選択すると、結果は4行になります。しかし、JUST nidで個別を選択すると、結果は2行になります。私はちょうどのNID上の明確な選択しようとしている
CHRIS

2
SQLでのグループ化の仕組みを誤解していると思います...説明していることを行うには、選択したフィールドからタイプ列を削除する必要があります
Clive

7

DISTINCTは、実際にはSELECTのグローバルなポスト修飾子です。つまり、SELECT ALL(すべての回答を返す)とは対照的に、SELECT DISTINCT(すべての一意の回答を返す)です。したがって、単一のDISTINCTは、指定したすべての列に作用します。

これにより、1つの列で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サーバーのバージョンに対応するマニュアルで、「distinct e.nid AS nid FROM mcc_notify_event_queue e INNER JOIN node n ON e.nid」を1行目で使用するための正しい構文を確認してください:SELECT e。*、n.type ASタイプ、n.status ASステータス、n.title ASタイトル、個別のe.nid AS anid FROM {mcc_notify_event_queue} e INNER JOIN {node} n ON e.nid = n.nid GROUP BY e.time ORDER BY e.time ASC; アレイ()
CHRIS 14

e。*とe.nidを使用できないため、エラーがスローされます。上で述べたように、フィールドを書き出す必要があります。
Scott Joudry、2014

まだエラーが発生します。コードを$ event_table-> fields( 'e'、array( 'nid'、 'time'、 'event_type'))に変更するだけです//イベントからフィールドを選択する
CHRIS

その場合でも、nidを2回選択しているため、エラーが発生します。$ event_table-> fields( 'e'、array( 'time'、 'event_type'))を試してください
Scott Joudry

それでもエラーが発生しますe.nid AS nid FROM my_module_event_queue e INNER JOIN node n ON e.nid 'at line 1:SELECT e.time AS time、e.event_type AS event_type、n.type AS type、n.status AS status、 n.title ASタイトル、明確なe.nid AS nid FROM {my_module_event_queue} e INNER JOIN {node} n ON e.nid = n.nid GROUP BY e.time ORDER BY e.time ASC;
CHRIS、2014

-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
明確な機能は、それの引数ではなく、文字列としてブール値をとります。
Felix Eve
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.