【问题标题】:Yii working with criteriaYii 使用标准
【发布时间】:2012-12-04 12:00:33
【问题描述】:

我有两张桌子orderorder_version

order

|  id |
|  1  |
|  2  |


order_version
| id | order_id | status |
| 1  |     1    |    0   |
| 2  |     2    |    0   |
| 3  |     1    |    1   |
| 4  |     1    |    2   |

我想查找所有已更改版本的订单。这意味着我只想通过id='1' 获得订单,因为另一个没有更改并且只有一个版本。
试过这个:

1)   $criteria = new CDbCriteria();
2)   $criteria->with = array('orderVersions');
3)   $criteria->addCondition("(SELECT MAX(status)  FROM order_version) != '0'");
4)   $criteria->addInCondition('order.id', $orderArray);        
5)   $criteria->order = 'order.id DESC';
6)   $orders = Order::model()->findAll($criteria);

$orderArray变量是orderids的数组。

首先问题出在第4行。

Column not found: 1054 Unknown column 'order.id' in 'where clause'

如果我只做id 而不是order.id 那么我有

Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous.

第 5 行同样的问题。
另:yii中的子查询我真的不知道怎么用,就是第3行了。
有什么建议吗?

【问题讨论】:

  • Yii 不关心原始表名,在本例中为order,它只关心关系名称。原始表始终别名为 torder_version 在这种情况下为 orderVersions
  • 好的,有了别名就很清楚了,谢谢。子查询呢?实际上,如果我将order_version 替换为orderVersions,则会出现错误Table 'imdb.orderVersions' doesn't exist。也许是因为 WHERE 子句?

标签: yii criteria


【解决方案1】:

order.id 代替t.id

这是因为当您使用$criteria->with 选项时,您将该表加入到查询中,因此将有两个id 字段,一个在order 表中,一个在order_version 表中。

Yii 通常会给你正在查询的主表(在这种情况下为order)一个别名t,我认为通常会给任何通过关系连接的表一个关系名称的别名。

如果您想获得 yii 使用的实际别名,可以使用 getTableAlias。但我认为你不能在你的情况下使用它,因为你静态地调用findAll()。如果你在模型上下文中使用它,你可以这样称呼它:

$alias = $this->getTableAlias();

或者像这样,如果您在默认范围或其他地方使用,您不想运行额外的检查或引用别名;

$alias = $this->getTableAlias(false,false);

【讨论】:

  • 好的,非常感谢。但是无论我在哪里称呼它,我都会得到t。我愿意:$alias = Order::model()->getTableAlias();
  • getTableAlias() 在您从模型中调用它时更有用,即不像您调用 findAll() 那样静态地调用它,这只是一些额外的信息来尝试解释如何在其他模型中使用案例。尝试只使用 t.id 而不是 order.id?
【解决方案2】:

从您的文本中我得出的结论是,您希望获得所有状态不等于 0(或大于零)的订单?试试这个:

$criteria = new CDbCriteria(array(
  'together' => TRUE,
  'with' => array('orderVersions' => array(
  'having' => 'MAX(`orderVersions`.`status`) > 0'
)),
'order' => '`t`.`id` DESC'
));
$criteria->addInCondition('`t`.`id`',$orderArray);

如果您只想要最高版本但状态高于 0 的分组订单:

$criteria = new CDbCriteria(array(
  'together' => TRUE,
  'with' => array('orderVersions' => array(
  'having' => 'MAX(`orderVersions`.`status`) > 0'
)),
'order' => 'MAX(`t`.`id`) DESC',
'group' => '`t`.`id`'
));
$criteria->addInCondition('`t`.`id`',$orderArray);

【讨论】:

  • 效果很好,除了一件事。 findAll() 返回正确的订单,但它在表中遇到的第一个 order_version。例如:关于我的问题中的表描述,如果我这样做 MAX(orderVersions.status) = 2 它只返回正确的第一个订单,但也返回第一个版本。是否可以退回第一个订单但包含所有版本?
  • 是的,删除'having' 子句,并在'order' 子句后添加'limit' => 1,同时删除'group' 子句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多