mysql - 当使用联合占位符时,似乎被联合中使用的初始选择中的值替换

标签 mysql drupal-7 dynamic-queries

这或多或少与这个How to preserve the order of the fields to be selected when using $query->addExpression()有关

我正在做的是在多个表上创建一个union。但我还需要知道这些值来自哪个表。所以我只添加如下内容:$query->addExpression(':table', 'table_name', array(':table' => $table_name));

问题是,一旦您建立联合,表名就会被第一个查询中的表名替换。

检查下面的例子:

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

$table_name = 'table_two'; 
$query_2 = db_select('table_two', 't2');
$query_2->fields('t2', array('field_1', 'field_2'));
$query_2->addExpression(':table', 'table_name', array(':table' => $table_name));    

$table_name = 'table_three';
$query_3 = db_select('table_three', 't3');
$query_3->fields('t3', array('field_1', 'field_2'));
$query_3->addExpression(':table', 'table_name', array(':table' => $table_name));

如果我们单独检查选择,它们看起来都很好,您会得到预期的结果,但是当使用 union 时,您只会在各处看到 table_one

// dpq($query_1) - OK 
SELECT t1.field_1 AS field_1, t1.field_2 AS field_2, 'table_one' AS table_name
FROM 
{table_one} t1

// dpq($query_2) - OK
SELECT t2.field_1 AS field_1, t2.field_2 AS field_2, 'table_two' AS table_name
FROM 
{table_two} t2

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

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

如果你有想法就太好了,因为我已经为此思考了一段时间......

最佳答案

睡了几个小时后,我找到了这个函数:

  // @file includes/database/select.inc
  public function arguments() {
    // ....

    // If there are any dependent queries to UNION,
    // incorporate their arguments recursively.
    foreach ($this->union as $union) {
      $args += $union['query']->arguments();
    }

    return $args;
  }

并且由于查询中的所有选择都具有相同的键:table,因此您最终只会得到一个参数而不是您。

解决方案:只需确保为占位符使用不同的键即可。

因此,如果我们在上面的示例中替换这些行(注意 :table_1 & :table_2 而不是 :table:

$query_2->addExpression(':table_1', 'table_name', array(':table_1' => $table_name));
$query_3->addExpression(':table_2', 'table_name', array(':table_2' => $table_name));

瞧,终于得到了预期的结果。希望它能帮助某人,半天都在试图弄清楚为什么会发生这种情况。

SELECT t1.field_1 AS field_1, t1.field_2 AS field_2, 'table_one' AS table_name
FROM 
{table_one} t1 UNION ALL SELECT t2.field_1 AS field_1, t2.field_2 AS field_2, 'table_two' AS table_name
FROM 
{table_two} t2 UNION ALL SELECT t3.field_1 AS field_1, t3.field_2 AS field_2, 'table_three' AS table_name
FROM 
{table_three} t3

关于mysql - 当使用联合占位符时,似乎被联合中使用的初始选择中的值替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11782682/

相关文章:

css - Drupal megamenu : how to get rid of blue backgrounds on hover in IE8/9?

sql - 考虑到动态查询的索引大平面表的最佳方式

php: oop 问题。可能非常基本

德鲁帕尔 7 : How to add translated nodes to the menu system

java - 重复键更新时的 Derby JavaDB 查询

css - 如何使用 css 自定义 COUNT 个节点

sql - 在Grails中动态生成SQL查询

php - 为什么这个不更新数据库中的位置,而另一个则更新

mysql - 如何将 CONCAT_WS 与 COALESCE 一起使用?