How to preserve the order of the fields to be selected when using $query->addExpression()

本秂侑毒 提交于 2019-12-11 04:08:33

问题


I'm using Drupal 7 and I have to make a union on multiple tables. For the union to work some conditions have to be met:

  1. same number of columns
  2. same data type
  3. same order

Some of the tables are missing a column so in order to compensate for that I just add it with something like this: $query->addExpression(':field_1', 'field_1', array(':field_1' => NULL));. So at this point condition 1 & 2 are satisfied, but the order of the fields in the select is different.

See example bellow:

  $query_1 = db_select('table_one', 't1');
  $query_1->fields('t1', array('field_1', 'field_2'));

  $query_2 = db_select('table_two', 't2');
  if (true) {
    $query_2->fields('t2', array('field_1'));
  } else {
    $query_2->addExpression(':field_1', 'field_1', array(':field_1' => NULL));
  }
  $query_2->fields('t2', array('field_2'));        

  $query_3 = db_select('table_three', 't3');
  if (false) {
    $query_3->fields('t3', array('field_1'));
  } else {
    $query_3->addExpression(':field_1', 'field_1', array(':field_1' => NULL));
  }
  $query_3->fields('t3', array('field_2'));

And the result is:

// dpq($query_1);
SELECT t1.field_1 AS field_1, t1.field_2 AS field_2
FROM {table_one} t1

// dpq($query_2);
SELECT t2.field_1 AS field_1, t2.field_2 AS field_2
FROM {table_two} t2

// dpq($query_3);
SELECT t3.field_2 AS field_2, '' AS field_1
FROM {table_three} t3

// dpq($query_1->union($query_2)->union($query_3));
SELECT t1.field_1 AS field_1, t1.field_2 AS field_2
FROM {table_one} t1 
UNION SELECT t2.field_1 AS field_1, t2.field_2 AS field_2
FROM {table_two} t2 
UNION SELECT t3.field_2 AS field_2, '' AS field_1
FROM {table_three} t3

Seems that using $query->addExpression will not guarantee the position of the field to be where you'd expect it to be. Look at the dump of the 3rd query where addExpression has been used. Any ideas on how to solve this issue?


回答1:


This is the only workaround I found to keep the order. Use an expression even if that field exists or not. That way the order is the one that you'd expect:

if (TRUE) {
  // To keep the order of the fields we have to use this hacky way.
  // Use a function that will not modify the string
  $query->addExpression("IFNULL(table_name.field_name, '')", 'field_name_alias');
} else {
  $query->addExpression(':field', 'field_name_alias', array(':field' => NULL));
}


来源:https://stackoverflow.com/questions/11782454/how-to-preserve-the-order-of-the-fields-to-be-selected-when-using-query-addexp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!