为什么 whereHas 多对多关系查询有时失效?

关联关系:

public function territory()
{
      return $this->belongsToMany(
      Territory::class,
      'territory_hospital_relations',
      'hospital_id',
      'territory_id'
      )->withTimeStamps();
}.

查询:
a.

if(!empty($titles)){$model->whereIn('title', $titles);}

b.

if(!empty($territoryIds)){
$model->whereHas('territory', function ( $query) use ($territoryIds) {
   $query->whereIn('territory.id', $territoryIds);
  });
  }

ps:a,b同时执行的时候,筛选有时有效(下1),有时失效(下2)

打印的SQL查询:
1.

SELECT
    count( * ) AS AGGREGATE 
FROM
    `hospitals` 
WHERE
    `title` IN ( 北京电力医院 ) 
    AND EXISTS (
    SELECT
        * 
    FROM
        `territory`
        INNER JOIN `territory_hospital_relations` 
        ON `territory`.`id` = `territory_hospital_relations`.`territory_id` 
    WHERE
        `hospitals`.`id` = `territory_hospital_relations`.`hospital_id` 
        AND `territory`.`id` IN ( 134 ) 
        AND `territory`.`deleted_at` IS NULL 
    ) 
    AND `hospitals`.`deleted_at` IS NULL #有结果

2.

SELECT
    count( * ) AS AGGREGATE 
FROM
    `hospitals` 
WHERE
    `title` IN ( 北京电力医院 ) 
    AND EXISTS (
    SELECT
        * 
    FROM
        `territory`
        INNER JOIN `territory_hospital_relations` 
        ON `territory`.`id` = `territory_hospital_relations`.`territory_id` 
    WHERE
        `hospitals`.`id` = `territory_hospital_relations`.`hospital_id` 
        AND `territory`.`id` IN ( 84 ) 
        AND `territory`.`deleted_at` IS NULL 
    ) 
    AND `hospitals`.`deleted_at` IS NULL #没结果,如果不加title in (北京电力医院)的限制,结果集中存在territory的ID是84的数据

3.

SELECT
    `territory`.*,
    `territory_hospital_relations`.`hospital_id` AS `pivot_hospital_id`,
    `territory_hospital_relations`.`territory_id` AS `pivot_territory_id`,
    `territory_hospital_relations`.`created_at` AS `pivot_created_at`,
    `territory_hospital_relations`.`updated_at` AS `pivot_updated_at` 
FROM
    `territory`
    INNER JOIN `territory_hospital_relations` 
    ON `territory`.`id` = `territory_hospital_relations`.`territory_id` 
WHERE
    `territory_hospital_relations`.`hospital_id` IN ( 3292 )  #北京电力医院的id是3292
    AND `territory`.`deleted_at` IS NULL #这条sql的结果territory的值只有84,134
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 5

看起来太累了,好好排版吧

4年前 评论
wenjoying (楼主) 4年前

$book->chapters->pluck('id'); 偶尔(1/20概率)会少一部分数据,不知道为什么,

后面先用了 Chapter::select('id')->where('book_id', $book['id'])->pluck('id');

4年前 评论
wenjoying (楼主) 4年前
  1. 尽量少用 whereHas,因为他最后转成的 sql 是 where exist,会增加数据库压力
  2. 如果你已经要用 whereHas 才能实现需求,基本上说明表结构设计不佳
4年前 评论
十七岁程序员想当歌手 4年前
sethhu 4年前
张雷

@di-gua 你说的这个比废话还废话,楼主问的问题你这答非所问还真是到了一个境界。

用wherehas能增加多少所谓的数据库压力我不知道,代码合理的前提下至少我没觉得用wherehas增加什么数据库压力,我前年开发的接口日均2000万次左右调用里面也有用到这个方法。MySQL数据库服务器也只是阿里云比较低端的系列,后台监控数据库还有较大的承载余地,读写还全在一个数据库服务器里。

还有用到wherehas就是表结构设计不合理?更莫名其妙,怎么样的设计可以完全不用wherehas又能用你所谓更温柔的不让数据库有压力,又能成为你所说的合理?

编程十多年看到这样的回答就觉得搞笑,你不说没人当你是哑巴,也没人求着你让你解答,非要答非所问的打几个字找存在感?

你怎么不说用框架还降低了php效率?

框架也好,数据库也罢,甚至是编程语言,永远记住它只是一个实现你需要完成目标的工具,别被它玩了!任何东西要看自己开发的产品是什么体量,假如我开发的产品用户体量不大,Access2003这个数局库都搓搓有余。~

睡前刷下论坛看到你这样回答楼主问题真觉得搞笑!

4年前 评论
小李世界 4年前
张雷 (作者) 4年前
张雷 (作者) 4年前
JerryBool 4年前
Egfly 4年前

到最后还是没解决。测试数据库数据都对,正式数据库就不行;都是阿里云的服务器,大版本都是5.7的,小版本不一样,正式的版本低一些(好像是5.7.18);正式的暂时没有发现其他数据错误,也可能没有类似查询。后来想是不是in和exists同时使用的问题,网上查询了一下,没找到类似问题。暂时解决方式是把in那边的数据改为循环like后数据正常(本来想限制title只能输入一个,这样直接用=,但数据也是错误的,不清楚原因,只好改为like了)。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!