php - 在 Laravel Eloquent 模型中使用特殊的 union 函数

标签 php mysql laravel model eloquent

我已经开始使用 Laravel 开发一个网站,并且我几乎通过我在这里找到的官方文档和答案找到了所有内容。然而,有一件事 - 尽管我已经找到了一种方法 - 我有一种感觉可以用另一种比我现在正在做的更优化的方式来完成。让我解释一下。

对于我的网站,我有一个名为“球员”的表,其中包含从足球比赛中提取的一些球员的数据。假设结构如下:

<小时/>

ID(int,主键,A_I)

GameID (int, unique)//游戏使用的内容

玩家姓名

数据(基本上是许多不同的列)

<小时/>

由于我网站的目的是允许用户对游戏内容进行修改,所以我还有另一个表,我称之为“userplayers”,我用它来对原始表上存在的玩家进行修改,或添加新的。其结构类似于“players”表,但只添加了一列,称为 userID,用于标识哪个修改属于哪个用户。

<小时/>

ID(int,主键,A_I)

GameID(int,与userID一起唯一)

玩家姓名

数据(基本上是许多不同的列)

UserID(int,与GameID一起唯一)

<小时/>

如果我在 userplayers 表上添加一个条目,如果该条目与玩家表上的任何条目具有相同的 GameID(并且创建它的用户已登录),那么在运行时它会覆盖玩家表条目。如果新条目的 GameID 不存在于原始玩家表中,则它会被附加到其中。

如果用户未登录,那么我只返回玩家表。

通过使用 eloquent laravel 模型,我可以在用户未登录时轻松检索玩家表。但是,我无法找到一种仅使用核心 eloquent 返回整个数据库 + 用户创建的内容的有效方法模型函数。

过去(没有 Laravel)我使用这个数据库查询:

SELECT * FROM (SELECT *, NULL FROM players WHERE NOT EXISTS (SELECT * FROM userplayers WHERE players.gameid=userplayers.gameid AND userId=$userId) UNION (SELECT * FROM userplayers WHERE userId=$userId)) AS pl;

我“发现”在 Laravel 中执行此类操作的方法是在 Players 模型中添加本地范围,如下所示:

public function scopeIncludeCustom($query, $user)
{
    return \DB::select('SELECT * FROM (SELECT *, NULL FROM players WHERE NOT EXISTS (SELECT * FROM userplayers WHERE userplayers.gameid=players.gameid AND userId='.$user.') UNION (SELECT * FROM userplayers WHERE userId='.$user.')) AS players_full);
}

但是您可以理解,这不会按范围返回 $query,而只是返回一个 php 数组,我认为这不是执行此操作的正确方法。例如,当我只是搜索玩家表(不使用用户创建的内容)时,返回结果所需的时间比使用自定义内容返回结果要短得多。

任何想法都将受到极大的赞赏。

最佳答案

因此,经过几天的研究我的问题和可能的解决方案,我想出了这个解决方案。

所以,让我们一步一步来。

<小时/>

我有一个“玩家”模型,它从“玩家”表中获取数据。

我还有一个“Userplayer”模型,它从“userplayers”表中获取数据。

<小时/>

我必须在这两个模型之间创建关系。 “players”表中的条目可能在“userplayers”表中具有许多与其相关的条目。因此,在玩家模型中我添加了以下内容:

public function userplayers()
{
    return $this->hasMany('App\Userplayer', 'gameid', 'gameid');
}

Userplayer模型中,我添加了以下内容:

public function player()
{
    return $this->belongsTo('App\Player', 'gameid', 'gameid');
}
<小时/>

请求数据时,第一步是从“players”表中删除与“players”表中返回的任何行具有相同“GameId”的每一行。

这是在我的 SearchPlayerController 中执行此操作的代码:

$orig_players = \App\Player::whereDoesntHave('userplayers', function ($query) use($user) 
{
    $query->where('userId', $user);
})->get();

同时,我需要从“userplayers”表中获取具有我想要的“userid”的每一行

$userplayers = \App\Userplayer::where([
                ['pesid', $search]
            ])->get();

现在,我只需合并 2 个结果(我无法使用 UNION,因为我从“players”表中获取的数据少了一列)。

$players = $orig_players->merge($userplayers)
            ->sortBy('registeredName')
            ->take($limit);

一切都运行得很好,而且比以前快得多!

关于php - 在 Laravel Eloquent 模型中使用特殊的 union 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52985307/

相关文章:

PHP递归目录路径

php - 如何将我的 Android 应用程序连接到我的 PHP/MySQL 后端?

php - 如何编辑 echo $OUTPUT->main_content() MOODLE

php - 在多个条件下返回零结果 codeigniter

mysql - 如何在mysql事件中使用多个sql语句?

php - 在 Laravel 项目中使用 Drupal API 时函数重新声明错误

php - 单独的查询是否足够好,或者我可以做某种连接吗?

mysql - 从 Magento 数据库中提取 SKU、制造商和自定义属性

laravel - 如何更改 Laravel 中的身份验证模型

laravel - 从 laravel 分形中删除数据