【问题标题】:PHP/Laravel get rows with certain column valuesPHP/Laravel 获取具有特定列值的行
【发布时间】:2021-06-01 07:36:07
【问题描述】:

从链接图像中可以看出,我想查询具有相同章节号的记录(跳过零)。假设我有 50 个章节,那么查询将产生 50 个集合,每个集合对应于某个列值,即章节号。

如何将查询限制在我的 Laravel 控制器中?

【问题讨论】:

  • 相同的已知章节号或多个按章节号处理的组?
  • 您的数据库设计不佳。在我看来,当您将章节设置为 0 时,您打算将其作为章节标题。我认为您需要一个章节标题表,章节模型可以在 belongsTo 关系中链接到该表。
  • @JustCarty 是的,你是对的。感谢您的提示。
  • @apokryfos 我想获取组,就像在图像中绘制一样。
  • 我是这么认为的。这设计得很糟糕,因为你如何知道 ID 1 是第 1 章,而 ID 9 是第 2 章?不查看所有内容,或者选择所有第 0 章,并从列表中获取n,这很棘手。请考虑利用关系数据库的性质。

标签: php laravel recordset


【解决方案1】:

获取章节组,喜欢画图

$chapters = Translation::where('chapter', '!=', 0)->get()->groupBy('chapter');

【讨论】:

  • 如果我没记错的话,这会返回一个集合。它不是查询,也不是可分页的。在这种情况下你有什么建议?
  • 请检查此解决方案的分页stackoverflow.com/a/67784879/16045221
【解决方案2】:

没有分页:

$chapters = Translation::where('chapter', '!=', 0)->get()->groupBy('chapter');

分页:

$posts = Translation::where('chapter', '!=', 0)->orderBy('chapter', 'ASC')->paginate($request->get('per_page', 2));
$grouped_by_chapter = $posts->mapToGroups(function ($post) {
    return [$post->chapter => $post];
});
$posts_by_chapter = $posts->setCollection($grouped_by_chapter);

了解更多:https://laravel.com/docs/8.x/collections#method-groupby

【讨论】:

    【解决方案3】:

    在不了解您的项目设置的情况下,我会说:

    $chapters = DB::table('translations')
        ->select('chapter')
        ->distinct()
        ->where('chapter', '<>', 0)
        ->get();
    

    如果你使用雄辩的模型:

    $chapters = Translations::get()
        ->pluck('chapter')
        ->flatten()
        ->filter()
        ->values()
        ->all();
    

    【讨论】:

      【解决方案4】:

      在 Elequent 模型中,您可以创建与“翻译”的 hasMany 关系,

      class Chapter extends Model
      {
          public function translations()
          {
              return $this->hasMany(Translation::class, 'chapter');
          }
      

      然后检索带有翻译的“章节”模型。

      $chapters = Chapter::with('translations')->get()
      

      【讨论】:

        【解决方案5】:

        其中很多答案都是正确的,但我想我会提供一种不同的方法。

        1。创建一个新表

        考虑创建一个名为 chapters 的附加表。
        使用以下命令执行此操作:

        php artisan make:model Chapter -m
        

        这将创建一个模型并进行迁移。
        迁移将如下所示:

        Schema::create('chapters', function (Blueprint $table) {
            $table->id();
            $table->integer('number')->unsigned();
            $table->string('heading');
            $table->timestamps();
        });
        

        2。将外键添加到旧表中

        然后根据您的屏幕截图修改您的模型。从这里开始,我假设和其他人一样,这个表叫做translation,模型叫做Transaltion
        您的新迁移应如下所示:

        Schema::create('translations', function (Blueprint $table) {
            $table->id();
            $table->foreignId('chapters_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
            $table->string('translation');
            $table->timestamps();
        });
        

        3。将关系添加到模型

        Translation型号

        public function chapters()
        {
            return $this->belongsTo(Chapter::class);
        }
        

        Chapter型号

        public function translations()
        {
            return $this->hasMany(Translation::class);
        }
        

        4。使用新关系

        您现在可以查询每个标题,而不必使用groupBy 或任何其他方法。
        以下是其中一些示例。

        4.1 我们有多少章?

        Chapter::count();
        

        4.2 第1章有多少个句子?

        Chapter::where('number', 1)->translations()->count();
        // or if you want to get a Collection of them
        Chapter::where('number', 1)->translations;
        // or if you just want a certain few columns
        Chapter::where('number', 1)->translations()->select('translation', 'sentence')->get();
        

        4.3 如何获取所有章节和对应的翻译?

        $chapters = Chapter::with('translations')->get();
        

        然后在你的刀片视图中,执行:

        @foreach ($chapters as $chapter)
            <h1>{{ $chapter->heading }}</h1>
        
            <p>Sentences:</p>
            @foreach ($chapter->translations as $sentence)
                <p>{{ $sentence }}</p>
            @endforeach
        @endforeach
        

        【讨论】:

        • 非常感谢朋友。
        • @Alistair 没问题,我想我会写下来。不管你是否想改变你的数据库——这很好——但这可能对其他发现它的人有用。如果使用得当,关系数据库真的很有用。
        【解决方案6】:

        假设你有一个Translation 模型并且想要使用Eloquent

        $chapters = Translation::where('chapter', '!=', 0)->get()->groupBy('chapter');
        

        上面说获取所有Translation,其中与它们关联的Chapter 不是Chapter zero,并按chapter 列对所有翻译进行分组。因此,如果您有 50 章节,您将拥有 50 集合,每个集合都包含其翻译。

        如果您只需要特定的列,您可以使用select() 并只提供您想要的列。

        【讨论】:

          猜你喜欢
          • 2023-03-16
          • 1970-01-01
          • 2018-05-09
          • 1970-01-01
          • 2011-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多