SQL Laravel Eloquent ORM "whereHas" 通过表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25179155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-01 02:24:30  来源:igfitidea点击:

Laravel Eloquent ORM "whereHas" through table

sqllaravelormeloquent

提问by Piotr Suchanek

Hey I have a problem with Laravel. I try to choose places that have city that I choose, through contact table.

嘿,我对 Laravel 有问题。我尝试通过联系表选择有我选择的城市的地方。

My model classes: Places class:

我的模型类: Places 类:

class Places extends Eloquent {
    public function contacts()
    {
        return $this->hasOne('Contacts');
    }
     public function clubs()
     {
        return $this->hasOne('Clubs');
     }    
}

Contacts class:

联系人类:

 class Contacts extends Eloquent {
     public function cities()
     {
         return $this->hasOne('Cities');
     }
   }

Cities class:

城市类:

 class Cities extends Eloquent {

 }

My query:

我的查询:

$view->clubs = Places::whereHas('contacts',function ($q) use($city_id){
           $q->where('contacts', function ($q) use($city_id){
               $q->where('id', $city_id);
            });
        })->get();

Error msg:

错误消息:

MySQL server version for the right syntax to use near 'where id= ?)) >= 1' at line 1 (SQL: select * from placeswhere (select count(*) from contactswhere contacts.places_id= places.idand contacts= (select * where id= 2223)) >= 1)

MySQL 服务器版本,用于id在第 1 行附近使用 'where = ?)) >= 1'的正确语法(SQL:select * from placeswhere (select count(*) from contactswhere contacts. places_id= places. idand contacts= (select * where id= 2223)) ) >= 1)

I know it is missing "from" cititesbut I do not know how to achieve it. Model relationships

我知道它缺少“来自”,citites但我不知道如何实现它。 模型关系

回答by Jarek Tkaczyk

You have 3 options using relations:

您有 3 个使用关系的选项:

1 most straightforward solution:

1个最直接的解决方案:

Places::whereHas('contacts',function ($q) use ($city_id){
       $q->whereHas('cities', function ($q) use ($city_id){
           $q->where('id', $city_id);
        });
    })->get();

2 the same as above but using this PR: https://github.com/laravel/framework/pull/4954

2 与上面相同,但使用此 PR:https: //github.com/laravel/framework/pull/4954

Places::whereHas('contacts.cities', function ($q) use ($city_id){
        $q->where('id', $city_id);   
    })->get();

3 Using hasManyThroughrelation:

3 使用hasManyThrough关系:

// Place model
public function cities()
{
  return $this->hasManyThrough('City', 'Contact');
}

// then
Places::whereHas('cities',function ($q) use ($city_id){
   $q->where('cities.id', $city_id);
})->get();


edit

编辑

Having your schema it's obvious that none of the suggest or your original setup can work.

有了您的架构,很明显,建议或您的原始设置都不起作用。

This is a many-to-many relation which in Eloquent is belongsToMany:

这是一个多对多的关系,在 Eloquent 中是belongsToMany

// Places model
public function cities()
{
  return $this->belongsToMany('Cities', 'contacts', 'places_id', 'cities_id')
    ->withPivot( .. contacts table fields that you need go here.. );
}

// Cities model
public function places()
{
  return $this->belongsToMany('Places', 'contacts', 'cities_id', 'places_id')
    ->withPivot( .. contacts table fields that you need go here.. );
}

Then you can call relations like this:

然后你可以像这样调用关系:

$city = Cities::first();
$city->places; // collection of Places models

// contacts data for a single city-place pair
$city->places->first()->pivot->open_hours; // or whatever you include in withPivot above

Now, there's another way to setup this, in case you need also Contactsmodel itself:

现在,还有另一种设置方法,以防您还需要Contacts建模:

// Places model
public function contact()
{
  return $this->hasOne('Contacts', 'places_id');
}

// Contacts model
public function city()
{
  return $this->belongsTo('Cities', 'cities_id');
}

public function place()
{
  return $this->belongsTo('Places', 'places_id');
}

// Cities model
public function contact()
{
  return $this->hasOne('Contacts', 'cities_id');
}

then:

然后:

$city = Cities::first();
$city->contact; // Contacts model
$city->contact->place; // Places model

hasManyThroughwon't work here at all

hasManyThrough根本不会在这里工作

回答by RMcLeod

As you know the city id and from this you want to find the corresponding place you can start at the city and work back to the place. To do this you will need to define the inverse of your relationships.

由于您知道城市 ID,因此您想要找到相应的地点,您可以从该城市开始并返回该地点。为此,您需要定义关系的倒数。

// Add this function to your Cities Model
public function contact()
{
    return $this->belongsTo('Contact');
}


// Add this function to your Contacts Model
public function place()
{
     return $this->belongsTo('Places');
}

Now you can query the City and find Place.

现在您可以查询 City 并找到 Place。

$place = Cities::find($city_id)->contact->place;

EDIT:Added missing return in functions

编辑:在函数中添加了缺少的返回

回答by Ra Com

SELECT * from pemeriksaan_ginekologi_iva where id in
(
SELECT m1.id
FROM pemeriksaan_ginekologi_iva m1 LEFT JOIN pemeriksaan_ginekologi_iva m2
 ON (m1.id_klien = m2.id_klien AND m1.id < m2.id)
WHERE m2.id IS NULL
) and id_klien in (select id from klien where id_kelurahan =1)
AND (hasil_periksa='IVA Negatif / Normal')  traslate to laravel