关于eloquent:Laravel-获取每个UID类型的最后一个条目

Laravel - Get the last entry of each UID type

我有一个表,其中包含1000多种产品的100个条目,每个条目都由一个唯一的UID标识。

1
2
3
4
5
6
7
8
9
10
11
ID  UID                 MANY COLUMNS    CREATED AT
1   dqwdwnboofrzrqww1   ...             2018-02-11 23:00:43
2   dqwdwnboofrzrqww1   ...             2018-02-12 01:15:30

3   dqwdwnbsha5drutj5   ...             2018-02-11 23:00:44
4   dqwdwnbsha5drutj5   ...             2018-02-12 01:15:31

5   dqwdwnbvhfg601jk1   ...             2018-02-11 23:00:45
6   dqwdwnbvhfg601jk1   ...             2018-02-12 01:15:33

...

我希望能够获得每个UID的最后一个条目。

1
2
3
4
ID  UID                 MANY COLUMNS    CREATED AT
2   dqwdwnboofrzrqww1   ...             2018-02-12 01:15:30
4   dqwdwnbsha5drutj5   ...             2018-02-12 01:15:317
6   dqwdwnbvhfg601jk1   ...             2018-02-12 01:15:33

在一个数据库调用中有可能吗?

我曾尝试使用DB和Eloquent,但到目前为止我得到的结果都是零或表的全部内容。

安迪


这很容易在MySQL中处理:

1
2
3
4
5
6
7
8
9
10
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
    SELECT UID, MAX(created_at) AS max_created_at
    FROM yourTable
    GROUP BY UID
) t2
    ON t1.UID        = t2.UID AND
       t1.created_at = t2.max_created_at;

将其转换为Eloquent会有些工作,但希望这可以为您提供一个良好的起点。

编辑:如果期望created_at可能是NULL,并且给定的UID可能只具有空创建的值,则可能要使用LEFT JOIN


您可以使用自我联接为每个UID选择最新行

1
2
3
4
5
select t.*
from yourTable t
left join yourTable t1 on t.uid = t1.uid
and t.created_at < t1.created_at
where t1.uid is null

使用laravel \\的查询生成器,它类似于

1
2
3
4
5
6
7
8
DB::table('yourTable as t')
    ->select('t.*')
    ->leftJoin('yourTable as t1', function ($join) {
        $join->on('t.uid','=','t1.uid')
             ->where('t.created_at', '<', 't1.created_at');
    })
    ->whereNull('t1.uid')
    ->get();

Laravel雄辩地选择所有具有created_at最大值的行

Laravel雄辩的团体,根据最新记录


已解决

感谢Tim和M Khalid的答复。我花了正确的路,但遇到了障碍,因此为什么要发布此解决方案。

工作正常:

1
2
3
4
5
6
7
8
        $allRowsNeeded = DB::table("table as s")
            ->select('s.*')
            ->leftJoin("table as s1", function ($join) {
                $join->on('s.uid', '=', 's1.uid');
                $join->on('s.created_at', '<', 's1.created_at');
            })
            ->whereNull('s1.uid')
            ->get();

但是我遇到了访问冲突,所以我不得不进入config / database.php并设置

1
'strict' => false,

在\\'mysql \\'配置中,该配置从SQL_MODE中删除ONLY_FULL_GROUP_BY。

再次感谢。


您可以使用orderBy()groupBy()使用eloquent来实现:

1
$data = TblModel::orderBy('id','DESC')->groupBy('uid')->get();

SELECT p1.* FROM product p1, product p2 where p1.CREATED_AT> p2.CREATED_AT group by p2.UID


您必须使用ORDER BYLIMIT SQL参数,这将导致您执行简单的SQL请求:

例如,在SQL中,您应该具有以下内容:

1
2
3
4
SELECT *
FROM table_name
ORDER BY `created_at` desc
LIMIT 1

这将返回表中的所有内容。结果将按" created_at "列降序排列。因此,第一个结果就是您要寻找的东西。然后" LIMIT "告诉您仅返回第一个结果,因此您不会拥有所有数据库。

如果您想雄辩地做到这一点,下面的代码将做同样的事情:

1
2
$model = new Model;
$model->select('*')->orderBy('created_at')->first();