Yii2:具有不同查询的 ActiveRecord

Posted

技术标签:

【中文标题】Yii2:具有不同查询的 ActiveRecord【英文标题】:Yii2: ActiveRecord with distinct query 【发布时间】:2017-10-09 16:41:56 【问题描述】:

我需要编写一个 ActiveRecord 查询,在其中获取行的所有字段,在一个字段中没有重复。

示例:这是一张书架。我想获取行的所有数据 不同的isbn。应该从重复中取出第一行。结果应该是 id 为 1,2,4 的行

id  | title   | isbn
--- | ------- | ------
1   | hello   | 1001
2   | world   | 1002
3   | this    | 1002
4   | is      | 1003
5   | funny   | 1003

我的第一次尝试是

$books = Books::find()->select('isbn')->distinct()->all();

但这仅填充 $books[0], $books[1], ... 中的 isbn 字段。

这可以使用 Yii2 ActiveRecord 吗?

【问题讨论】:

ActiveQueryselect 方法告诉Yii 选择哪些列,因此在这种情况下它不是您需要的。您希望查询如何处理其他列中的数据?那么,如果它选择了所有列,并且只返回 isbn 的不同值,它应该如何处理标题和 ids? 我想让 $books 填充 id 1、2 和 4 的所有字段,例如$book[0]=[1,'hello', 1001],... 而不仅仅是 isdn 字段。 【参考方案1】:

您可以为此使用groupBy()

$books = Books::find()->groupBy(['isbn'])->all();

但这会返回具有匹配 isbn 值的随机行,并且在某些 DBMS 中可能不起作用。您的要求太模棱两可,无法以可预测的方式处理。但是如果你想总是第一行,你可以使用子查询来获取匹配的isbnid

$query = (new Query())
    ->select(['MIN(id) as id, isbn'])
    ->from(Books::tableName())
    ->groupBy(['isbn']);
return Books::find()
    ->alias('book')
    ->innerJoin(['subquery' => $query], 'book.id = subquery.id AND book.id = subquery.id')
    ->all();

【讨论】:

【参考方案2】:

Yii2中对distinct属性的描述如下:

是否只选择不同的数据行。如果设置为 true,则 SELECT 子句将更改为 SELECT DISTINCT。 -- https://www.yiiframework.com/doc/api/2.0/yii-db-query#$distinct-detail

因此,如果您需要选择 'isbn' 的不同值,则应使用 distinct 属性传递 true,如下所示:

$books = Books::find()->select('isbn')->distinct(true)->all();

【讨论】:

以上是关于Yii2:具有不同查询的 ActiveRecord的主要内容,如果未能解决你的问题,请参考以下文章

使用 ActiveRecord 和 Yii2 记录实际的 SQL 查询?

如何将 DAO 查询转换为 Yii2 ActiveRecord。如何从连接表中选择和使用特定列

如何在 YII2 ActiveRecord 查询中说 (a AND b) OR (c AND d)?

yii2 的ActiveRecord

yii2中关联查询

Yii2中DAO