我有三个与library(tidyverse)
df %>%
group_by(Num) %>%
# create a temporary column PassFail1
mutate(PassFail1 = case_when(
all(PassFail == "PASS") ~ "PASS",
PassFail == "FAIL#NODATA" ~ "FAIL#NODATA",
any(grepl("FAIL", PassFail)) ~ "FAIL")) %>%
# remove the rows that have PASS mixed with FAIL in the same Num group
filter(!(PassFail == "PASS" & PassFail1 == "FAIL")) %>%
# remove duplicates
distinct(PassFail1, .keep_all = TRUE) %>%
# clean up
select(-PassFail1) %>%
ungroup()
#> # A tibble: 6 x 5
#> ID Type PassFail Slot Num
#> <fct> <fct> <fct> <dbl> <dbl>
#> 1 ID001 Length PASS 1.00 1111.
#> 2 ID001 Length PASS 1.00 1112.
#> 3 ID003 Length FAIL 2.00 1113.
#> 4 ID009 LengthTest FAIL 1.10 1114.
#> 5 ID023 LengthTest FAIL#NODATA 2.20 1115.
#> 6 ID027 LengthTest FAIL 3.10 1115.
关系相关的模型。
morph
可以通过Shipment
类有多个Status
个实例。
StatusHistory
我想获取 class Status extends Model {
//id, name
}
class Shipment extends Model {
public function latestStatus() {
return $this->morphOne('App\StatusHistory', 'model')->latest();
}
}
class StatusHistory extends Model {
public function model() {
return $this->morphTo();
}
public function status() {
return $this->belongsTo('App\Status', 'status_id');
}
}
具有特定Shipment
名称值的所有latestStatus
个实体。
Status
这不起作用,并返回状态为&#39;保留&#39;的所有实体,即使 Shipment::whereHas('latestStatus', function($query) {
return $query->whereHas('status', function($query) {
return $query->where('name', 'reserved');
});
})->get();
可能是其他内容。
有什么想法?
编辑(添加样本信息):
我有2批货。
所以:
电话应该只返回第一批货。
答案 0 :(得分:1)
最简单的解决方案是获取所有货件并在之后过滤它们:
Shipment::with('latestStatus.status')->get()->where('latestStatus.status.name', 'reserved')
根据您的数据库大小,这可能效率不高。
仅提取相关货件的查询:
Shipment::select('shipments.*')
->join('status_histories as sh', 'shipments.id', 'sh.model_id')
->join('statuses as st', 'sh.status_id', 'st.id')
->where('model_type', Shipment::class)
->where('st.name', 'reserved')
->where('created_at', function($query) {
$query->selectRaw('MAX(created_at)')
->from('status_histories')
->where('model_id', DB::raw('sh.model_id'))
->where('model_type', DB::raw('sh.model_type'));
})->get();