【问题标题】:Yii2 gridview showing more records than the tableYii2 gridview 显示的记录多于表格
【发布时间】:2016-02-25 17:28:45
【问题描述】:

我有两个mysql表:

拥有 51 条记录

  • 身份证
  • 姓名
  • ...

人员统计有 131 条记录

  • 身份证
  • peopleID
  • 日期
  • 星星
  • ...

如果我在 models/peopleSearch.php 中设置它

$query->joinWith('peopleStats');

GridView 显示 131 条记录。我如何设置该联接以获取每个人项目的最后一天的记录(使用 MAX(date) 的查询),以便 GridView 仅显示具有最新数据的 51 条记录?

谢谢

【问题讨论】:

  • 使用LEFT OUTER JOIN.....
  • 试试这个……$query = People::find();$query->join('LEFT OUTER JOIN', 'people_state', "people_table_id = people_state_table_id");
  • 谢谢 Vishu,但是那个似乎只进行了左外连接,这与 $query->joinWith('peopleStats'); 相同。做。我需要的是将日期与 peoplestats 表中最近日期的那些记录结合起来

标签: yii2


【解决方案1】:

这是ActiveDataProvider 支持的GridView 的常见问题。网格需要知道您的数据集中有多少个模型。同时,获取和实例化所有模型只是为了计算它们效率极低。这就是为什么ActiveDataProvider 从 SQL 获取模型总数的原因,假设结果集中的每一行都对应一个模型。

现在,您已经在查询中引入了 JOIN。这会增加结果集中的行数(在您的情况下从 51 增加到 131)。模型总数不是唯一的问题,你也应该有分页的问题。请注意,您可能会使用 all() 函数来获取所有模型(如 People::find()->joinWith('peopleStats')->all() 中的函数足够聪明,可以删除冗余行,因此您将获得 51 个带有 all() 的模型。

现在,有几种解决方法。首先,在数据提供者中执行joinWith() 的唯一原因是当您需要对相关数据进行过滤或排序时。如果不是这种情况,请使用with(),你会没事的。

如果您确实需要对相关数据进行过滤/排序,还有另一种解决方法,即仅从主表 ->select('people.*') 中选择列。您仍然可以在网格视图中引用相关数据,它只是延迟加载。

如果您的结果集很小,特别是如果您不打算使用分页,请考虑切换到ArrayDataProvider

在您的具体情况下,我建议您只创建另一个 hasOne 关系,例如 peopleStatsLast,并在其中实现仅选择给定人员的最后一组统计信息的查询,然后延迟加载它。更多信息请查看MySQL reference

【讨论】:

  • 这正是我的情况。我需要过滤+排序这些字段。我会尝试设置与 hasOne 的新关系
  • 您可能希望使用ArrayDataProvider 而不是复杂的查询。
【解决方案2】:

使用这个查询就像.....

$query = People::find(); 
$query->join('LEFT OUTER JOIN', 'people_state', "people_table_id = people_state_table_id");

【讨论】:

    【解决方案3】:

    应该是这个查询

    $query = People::find()->
       join('LEFT OUTER JOIN', 'people_state', "people_table_id = people_state_table_id")->
       where("(peopleID, date) in ( select peopleID, max(date) from  peopleStats 
       group by peopleID)");
    

    【讨论】:

    • 感谢您的回答@scaisEdge。我收到这个错误:unspected ","。这是查询:
       $query = People::find() ->join('LEFT OUTER JOIN', 'PeopleStats', "People.socialID = PeopleStats.socialID") ->where( ( People.socialID, PeopleStats.date ) in ( select PeopleStats.socialID, max(date) from PeopleStats group by People.socialID ) ); 
    • 对不起,我忘记了引号“。我已经更新了答案
    猜你喜欢
    • 2016-07-13
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多