MySQL Select 其中状态数组和最后一次出现等于特定值
MySQL Select where in array of statuses and last occurrence equals specific value
假设我有这样一个 table:
id user_id status updateded_id
1 1 yes 2/5/2013
2 2 no 2/1/2013
3 3 yes 1/28/2013
4 2 yes 1/24/2013
5 2 no 1/20/2013
6 1 yes 1/16/2013
7 3 no 1/12/2013
8 4 yes 1/8/2013
9 5 yes 1/4/2013
10 5 no 12/31/2012
11 6 yes 12/27/2012
12 7 no 12/23/2012
13 6 yes 12/19/2012
14 4 yes 12/15/2012
15 3 no 12/11/2012
16 3 yes 12/7/2012
17 1 no 12/3/2012
18 1 yes 11/29/2012
我需要编写一个查询,仅当状态最近 updateded_id
为“是”时才选择 user_id
。
例如 user_id
1 会被选中而 user_id
2 不会。
我在一个复杂的 Larvel 查询构建器(Larvel 4.2 版)中写了这个。
结果是多个用户。
所以在这个查询中,用户应该只被选择一次,并且只有当状态 table 中的最后一次出现是 yes.
我试过了:
$query->join('mytable', function ($join) use ($statuses) {
->whereRaw('mytable.status in ('.$statuses.') )
->orderBy('mytable.updated_at', 'desc')
->limit(1);
});
和:
$query->join('statuses', function ($join) use ($statuses) {
->whereIn('mytable.status ,$statuses )
->orderBy('mytable.updated_at', 'desc')
->limit(1);
});
whereIn 和 whereRaw 函数出错。就像它们不存在一样。
所以,进步。在这个查询中,我可以找到一个具有 'yes' 作为最新状态的用户。我找不到一种方法让它通过这种逻辑选择所有用户:
SELECT s1.user_id
FROM statuses s1
WHERE s1.user_id = ( SELECT user_id
FROM statuses s2
WHERE s2.status IN ('yes', 'no') ORDER BY s2.updateded_id DESC LIMIT 1)
AND s1.status= 'yes';
你可以做到这一点。
一个用户有多个状态,您想根据最新状态获取用户对吗?
Eloquent 用户模型
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/*
* Get the user's statuses
*/
public function statuses()
{
return $this->hasMany(Status::class);
}
/**
* Get the user's latest status.
*/
public function latestStatus()
{
return $this->hasOne(Status::class)->latestOfMany('updated_at');
}
}
那么你可以这样写查询
return User::whereHas('latestStatus', function($query) {
$query->where('status', 'yes');
})->get();
您可以在 MySql 查询中使用 NOT EXISTS
,(我希望)您可以将其转换为 Laravel 代码:
SELECT s1.user_id
FROM statuses s1
WHERE s1.status = 'yes'
AND NOT EXISTS (
SELECT 1
FROM statuses s2
WHERE s2.user_id = s1.user_id AND s2.updateded_id > s1.updateded_id
);
参见demo。
我相信您正在寻找我所说的“过滤器连接”。我不熟悉Laravel,所以请接受MySQL:
SELECT t.user_id FROM table AS t
LEFT JOIN table AS filter ON (
filter.user_id = t.user_id
AND filter.updated_id > l.updated_id
)
WHERE filter.id IS NULL
AND t.status = 'yes';
使用你在问题中提供的数据,我的输出是:
1
3
4
5
6
我认为这满足了“最新状态为 'yes' 的用户”的要求。
假设我有这样一个 table:
id user_id status updateded_id
1 1 yes 2/5/2013
2 2 no 2/1/2013
3 3 yes 1/28/2013
4 2 yes 1/24/2013
5 2 no 1/20/2013
6 1 yes 1/16/2013
7 3 no 1/12/2013
8 4 yes 1/8/2013
9 5 yes 1/4/2013
10 5 no 12/31/2012
11 6 yes 12/27/2012
12 7 no 12/23/2012
13 6 yes 12/19/2012
14 4 yes 12/15/2012
15 3 no 12/11/2012
16 3 yes 12/7/2012
17 1 no 12/3/2012
18 1 yes 11/29/2012
我需要编写一个查询,仅当状态最近 updateded_id
为“是”时才选择 user_id
。
例如 user_id
1 会被选中而 user_id
2 不会。
我在一个复杂的 Larvel 查询构建器(Larvel 4.2 版)中写了这个。
结果是多个用户。 所以在这个查询中,用户应该只被选择一次,并且只有当状态 table 中的最后一次出现是 yes.
我试过了:
$query->join('mytable', function ($join) use ($statuses) {
->whereRaw('mytable.status in ('.$statuses.') )
->orderBy('mytable.updated_at', 'desc')
->limit(1);
});
和:
$query->join('statuses', function ($join) use ($statuses) {
->whereIn('mytable.status ,$statuses )
->orderBy('mytable.updated_at', 'desc')
->limit(1);
});
whereIn 和 whereRaw 函数出错。就像它们不存在一样。
所以,进步。在这个查询中,我可以找到一个具有 'yes' 作为最新状态的用户。我找不到一种方法让它通过这种逻辑选择所有用户:
SELECT s1.user_id
FROM statuses s1
WHERE s1.user_id = ( SELECT user_id
FROM statuses s2
WHERE s2.status IN ('yes', 'no') ORDER BY s2.updateded_id DESC LIMIT 1)
AND s1.status= 'yes';
你可以做到这一点。
一个用户有多个状态,您想根据最新状态获取用户对吗?
Eloquent 用户模型
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/*
* Get the user's statuses
*/
public function statuses()
{
return $this->hasMany(Status::class);
}
/**
* Get the user's latest status.
*/
public function latestStatus()
{
return $this->hasOne(Status::class)->latestOfMany('updated_at');
}
}
那么你可以这样写查询
return User::whereHas('latestStatus', function($query) {
$query->where('status', 'yes');
})->get();
您可以在 MySql 查询中使用 NOT EXISTS
,(我希望)您可以将其转换为 Laravel 代码:
SELECT s1.user_id
FROM statuses s1
WHERE s1.status = 'yes'
AND NOT EXISTS (
SELECT 1
FROM statuses s2
WHERE s2.user_id = s1.user_id AND s2.updateded_id > s1.updateded_id
);
参见demo。
我相信您正在寻找我所说的“过滤器连接”。我不熟悉Laravel,所以请接受MySQL:
SELECT t.user_id FROM table AS t
LEFT JOIN table AS filter ON (
filter.user_id = t.user_id
AND filter.updated_id > l.updated_id
)
WHERE filter.id IS NULL
AND t.status = 'yes';
使用你在问题中提供的数据,我的输出是:
1
3
4
5
6
我认为这满足了“最新状态为 'yes' 的用户”的要求。