さらに調べましたが、これを説明するドキュメントは実際には見つかりませんでした。
私が必要としたのは、ユーザーのデータを保持する他の2つのテーブルとユーザーテーブルを結合する方法でした。ただし、他の2つのテーブルはユーザーテーブルと「1対多」の関係にあります。つまり、ユーザーテーブルとこれらのテーブルの両方を同時に結合しようとすると、デカルト結合になります。 。ただし、必要なのは、特定のユーザーに関連付けられた他の2つのテーブルのレコード数をカウントすることだけなので、サブクエリでトリックを実行できるはずです。ただし、ビューとサブクエリに関するドキュメントが見つかりませんでした。ここで、私がしたことを説明します。
- 2つのダミーフィールドを作成しました
hook_views_data()を介して2つのダミーフィールド(「ダウンロード」および「リッスン」と呼びます)を作成しました。フィールドの定義を以下にリストします。
function hook_views_data() {
$data['users'] = array(
'downloads' => array(
'title' => t('Downloads'),
'field' => array(
'handler' => 'views_handler_field_numeric',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_numeric',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
),
'listens' => array(
'title' => t('Listens'),
'field' => array(
'handler' => 'views_handler_field_numeric',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_numeric',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
)
),
);
これで、ユーザーのビューを設定すると、「ダウンロード」フィールドと「リスニング」フィールドが表示されます。ただし、クエリを実行しようとすると、ダミーフィールドがすべてダミーフィールドであるため、エラーが発生します。それらは存在しません。これらのフィールドの唯一の目的は、hook_views_query_alter()の実装に、いくつかの置き換えを行う必要があることを知らせることです。
- hook_views_query_alter()を実装する
ここでのコツは、指定されたクエリに「ダウンロード」または「リスニング」フィールドが含まれているかどうかを確認することです。存在する場合、クエリからフィールドを削除し、サブクエリに置き換えます。この関数の実装は以下の通りです。
function mta_views_query_alter(&$view, &$query) {
foreach ($query->fields as $field_key => &$field_values) {
if ($field_values['table'] == 'users') {
switch ($field_values['field']) {
case 'downloads':
unset($query->fields[$field_key]);
$query->add_field(null, "(SELECT COUNT(*) FROM {fileusage} fu WHERE fu.externaluser = {users}.uid AND fu.action = 0)", $field_key);
break;
case 'listens':
unset($query->fields[$field_key]);
$query->add_field(null, "(SELECT COUNT(*) FROM {fileusage} fu WHERE fu.externaluser = {users}.uid AND fu.action = 1)", $field_key);
break;
}
}
}
}
サブクエリの削除されたフィールドのエイリアスを再利用していることに注意してください。そうすることで、Viewsは、サブクエリから返された値が実際にはダミーフィールド(結局は存在しません)から返されたものだと考えます。
そうです。デカルト結合を取得していないため、「ダウンロード」と「リッスン」の両方が正しくカウントされます。