【问题标题】:Eloquent, how to get calculated sum of fields in a new field雄辩,如何获得新字段中的字段总和
【发布时间】:2019-02-17 21:09:34
【问题描述】:

我有一个 DB 表 students,其中包含每个科目的所有科目最终成绩,这是一个相当大的数字,以及许多其他字段,例如姓名等。

students(表格有100多列,每个单元格可以有一些预设的ID,后来被翻译成等级/一些愚蠢的反黑客技术,几个数字可以代表同一个等级/)

|| name  || surname|| section || math1||math 2||math 16|| physics 1||physics 2 ||... ||
|| Jonah || Smith  ||  A4     || 17   || 19   || 0     || 193      ||          ||    
|| John  ||Doe     ||  A3     ||  0   || 0    || 34    ||12        ||  0       || ...||
|| Jane  ||Doe     ||  A3     ||  0   || 0    || 48    ||12        ||  154     || ...||
|| Martin||Doe     ||  A3     || 17   || 34   || 96    ||10        || 225      || ...||

理想的结果

|| avg.grade || name  || surname|| section || math1||math 2||math 16|| physics 1||physics 2||... ||
|| 0.92      || John  ||Doe     || A3      ||0   || 0    ||...    ||12        || 0       || ...||
|| 0.81      || Jane  ||Doe     || A3      ||0   || 0    ||...    ||12        || 154     || ...||

除了

之外,实际上没有其他相关的表
  • 内存表中的辅助,具有等级到 ID 表示
  • 科目和学生数据

我想被选中(使用 Laravel 雄辩模型)所有字段和“最终成绩”,所有选中的总和是什么......超过某个阈值。 (下面介绍

SELECT *, a FROM `students` WHERE 
`name` LIKE "J%" AND `surname` LIKE "D" AND `section` = 'A3'
enter code here
AND (if(`math16`='12',0.76, 0)
+if(`geometry26`='13',0.76, 0) +if(`physics13`='325',1, 0)
+if(`programming06`='551',1, 0) +if(`biology18`='271',0.916, 0) 
+ .... )/18.216 as a > 0.75

'12','13','25','551','271' - 是等级代码。

从技术上讲,我需要让所有学生获得或多或少相同的课程,并且对于给定的起始姓名字母具有一些平均成绩。 (我的意思是,如果我有 John,他参加了特定课程 [数学 16 成绩为 0.76,生物学 18 成绩为 0.91,...] 和 Jane [数学 16 成绩为 0.76,programming06 成绩为 100,...],我想要在没有其他学生的情况下,将他们的记录和他们的成绩总和放在一起。

可能还有其他一些可能性可以将所有具有相同字段的行放在一起,但我不知道该怎么做。 谢谢

【问题讨论】:

  • 您能否提供带有记录的students 表/模型的样本,以及您想要的输出如何?目前还不是很清楚。
  • 我的意思是用数据样本更新你的问题,你的 sql 语句并没有真正的帮助(imo)。还有您的相关表格(主题,...)
  • @HCK,添加了一些表格
  • @DCR:欢迎对原始发布者如何改进他的问题提出具体建议,但没有帮助的责骂 OP。
  • 我认为你应该对你的数据库进行一些不同的建模以解耦你的列。在学生表中有 >100 列它不是很有用,这是因为 - 我假设 - 学生不会同时参加所有这些课程。您可以有一个学生表(包含基本学生信息),然后是一个主题表,其中包含与该课程相关的所有成绩,还可以指定确定应用于该课程的实际成绩的算法......然后是另一个表您将学生与特定学期/课程期间的课程联系起来

标签: php laravel eloquent dynamicquery


【解决方案1】:

我不建议将主题保留在 students 表中,而是应该进一步探索规范化数据库并添加 subjectsstudent_subject 表。但是,对于您当前的设置,您可以考虑在模型上创建属性,然后附加它。

https://laravel.com/docs/5.7/eloquent-serialization#appending-values-to-json

class User {

    protected $appends = [
        'average_grade'
    ];

    public function getAverageGradeAttribute()
    {
        return $this->attributes['average_grade'] = ($this->math1 + $this->math2) / 2;
    }

}

这样做将允许您在视图中显示属性时简单地调用该属性,如下所示:

<table>
    <thead>
        <tr>
            <th>Student</th>
            <th>Average Grade</th>
        </tr>
    </thead>
    <tbody>
        @foreach($students as $student)
            <tr>
                <td>{{ $student->name }}</td>
                <td>{{ $student->average_grade }}</td>
            </tr>
        @endforeach
    </tbody>
</table>

【讨论】:

  • 谢谢, 1. 我不知道如何重构/规范化表格。原因是:预设的科目不是很大,而且很密集。 2. 我想过这样做,添加一个属性,但请求只是来自大约无数个(好吧,不是无数个,而是〜20 个:))。出于某种原因,我确信添加属性会影响每个查询。看来我错了谢谢
  • 另外,3. 这与科目和学生无关,但由于 NDA,我必须重新表述我的问题 :) 4.看起来我要在 where 子句中进行计算。否则非常耗时。我有数千条记录
  • 没问题阿列克谢。您可以做的最有效的事情是规范化您的数据库。以后再做这件事对您来说将非常耗时,而且只会阻止您扩展您的应用程序。
  • Ian,这个表已经有几十万条记录了%)。而且我不知道如何在不破坏所有其余部分的情况下对其进行规范化^_^。
  • -“学生记录”只是系统中的一个“砖块”。其中的每个字段都是加密的。只有在这个特定的查询中,我们才能访问一些字段,以便能够解密它们并计算一些结果。
【解决方案2】:

您可以执行以下操作来实现您的目的。假设您想要获取模型名称为“ModelName”的表的字段名称为 field1 和 field2 的表中 2 个字段的单个总和的总和,那么您可以执行以下操作:

$amount = ModelName::select(DB::raw('sum(field1 + field2) as total'))->get();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-17
    • 2021-10-07
    相关资源
    最近更新 更多