Views3 dan subkueri?

12

Saya memiliki pandangan yang menghasilkan kueri yang menggabungkan banyak hal. Ini menghasilkan gabungan kartesius, dan saya perlu "mengubah" gabungan menjadi subquery.

Saya telah melihat melalui dokumentasi, hasil pencarian Google dan sumber-sumber lain, tetapi saya tidak dapat menemukan deskripsi yang layak tentang bagaimana saya dapat mengkonfigurasi Tampilan untuk melakukan subkueri. Saya telah menggunakan hook_views_data () untuk mengonfigurasi hubungan (yang sekarang dijalankan sebagai gabungan). Apakah mungkin untuk mendefinisikan subqueries melalui hook_views_data (), atau apakah saya perlu mengambil pendekatan lain?

Setiap saran dihargai!

sbrattla
sumber

Jawaban:

5

Saya melihat lebih jauh, tetapi tidak dapat menemukan dokumentasi yang menjelaskan hal ini.

Apa yang saya butuhkan adalah cara untuk bergabung dengan tabel pengguna dengan dua tabel lain yang menyimpan data untuk pengguna. Namun, dua tabel lainnya berada dalam hubungan 'satu-ke-banyak' dengan tabel pengguna, yang berarti bahwa saya akan berakhir dengan gabungan Cartesian jika saya mencoba untuk bergabung dengan tabel pengguna dengan kedua tabel ini pada saat yang sama . Namun, karena semua yang saya butuhkan adalah untuk menghitung jumlah catatan di dua tabel lain yang terkait dengan pengguna tertentu, subquery harus dapat melakukan trik. Namun, saya tidak dapat menemukan dokumentasi apa pun tentang Tampilan dan subkueri - jadi inilah yang saya lakukan.

  1. Menciptakan dua bidang boneka

Saya membuat dua bidang boneka (yang saya sebut 'unduhan' dan 'mendengarkan') melalui hook_views_data (). Definisi bidang tercantum di bawah ini.

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

Sekarang, ketika Anda mengonfigurasi tampilan untuk pengguna, bidang 'Unduhan' dan 'Mendengarkan' akan muncul. Namun, mencoba menjalankan kueri sekarang akan menghasilkan kesalahan karena bidang dummy setelah semua adalah bidang dummy. Mereka tidak ada. Satu-satunya tujuan dari bidang ini adalah memberi sinyal kepada implementasi hook_views_query_alter () kami yang perlu dilakukan beberapa replacemenet.

  1. Terapkan hook_views_query_alter ()

Kuncinya di sini adalah untuk memeriksa apakah kueri yang diberikan mencakup bidang 'Unduhan' atau 'Dengarkan'. Jika ya, kami akan menghapus bidang dari kueri dan menggantinya dengan subkueri. Implementasi fungsi ini berjalan seperti di bawah ini.

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;
      }
    }
  }
}

Perhatikan bahwa kami menggunakan kembali alias dari bidang yang dihapus untuk subquery. Dengan begitu, Views akan berpikir bahwa nilai yang dikembalikan dari subquery sebenarnya berasal dari bidang dummy (yang setelah semua tidak ada).

Itu adalah. Kami tidak mendapatkan gabungan Cartesian dan 'unduhan' dan 'mendengarkan' dihitung dengan benar.

sbrattla
sumber
4

Saya menggunakan solusi sbrattla sampai saya perlu memiliki nilai filter inherit subquery. Saya sekarang menggunakan modul views_field_view untuk menyematkan tampilan terpisah yang melakukan kueri hitung. Saya bisa meneruskan nilai filter konteks ke tampilan tertanam melalui modul views_filterfield (yang saya tulis) yang membuat nilai filter tersedia sebagai bidang tampilan (dan karenanya token).

Kueri hitung sekarang berfungsi dan mewarisi filter terbuka pada kueri utama.

Cafuego
sumber