laravel 考勤获取未提交考勤的课程[已关闭]

8cdiaqws  于 2023-03-19  发布在  其他
关注(0)|答案(2)|浏览(192)

**已关闭。**此问题需要debugging details。当前不接受答案。

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
16小时前关门了。
这篇文章是9小时前编辑并提交审查的。
Improve this question
在laravel中创建考勤系统,需要检查提交了考勤的班级和挂起的班级。学生数据保存在学生表中。
考勤时,提交考勤的班级保存在attendence_dates表中。(用于检查哪一天上课以及数据是否最终提交)

public function up()
{
    Schema::create('attendence_dates', function (Blueprint $table) {                  
        $table->bigIncrements('id');
        $table->date('date')->default(date("Y-m-d"));
        $table->string('clas_name', 20)->nullable();
        $table->string('section_name',20)->nullable();
        $table->boolean('working')->default(false);
        $table->boolean('final')->default(false);
        $table->string('remarks', 100)->nullable();
        $table->unsignedBigInteger('updated_by')
          ->nullable(); 
        $table->timestamp('updated_at')
           ->useCurrent()->useCurrentOnUpdate();
    });
}

出勤表,其中学生的出勤以P和A状态保存。

public function up()
    {
        Schema::create('attendences', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('att_month')->default('0')->nullable();
            $table->date('att_date')->useCurrent();            
            $table->string('clas_name', 20)->nullable();
            $table->string('section_name',20)->nullable();                           
            $table->unsignedBigInteger('student_id')->nullable();
            $table->unsignedBigInteger('acc_id')->nullable();
            $table->enum('status', ['P', 'A'])->default('P');                
            $table->foreign('student_id')->references('id')->on('students')
                    ->onDelete('SET NULL')
                    ->onUpdate('CASCADE'); // SET NULL, CASCADE, RESTRICT, DO NOTHING, NO ACTION
            $table->foreign('acc_id')->references('acc_id')->on('students')
                    ->onDelete('SET NULL')
                    ->onUpdate('CASCADE');                                         
            $table->timestamps();
        });
    }

使用此代码从“students”表中获取所有现有的类和段。

$classAll   = DB::table('students')
    ->select('clas_name', 'section_name')
    ->groupBy('clas_name','section_name')
    ->orderBy('clas_name','ASC')
    ->orderBy('section_name','ASC')
    ->get();

这个函数用于获取提交了出勤率的班级和部门。

// FETCH POSTED CLASSES DATA
$posted = DB::table('attendence_dates')
        ->select('clas_name', 'section_name')
        ->where('date', $date)
        ->groupBy('clas_name','section_name')
        ->orderBy('clas_name','ASC')
        ->orderBy('section_name','ASC')
        ->get();

现在必须显示挂起的类,即未提交的类。我正在学习laravel,从搜索和文档中我得到了这个集合函数。尝试**$pending = $classAll->diff($posted);,但它给出错误“类stdClass的对象无法转换为字符串“。
还尝试了
$pending = $classAll->diffKeys($posted);**,但没有给出任何错误,但没有得到所需的结果。总数减少,但没有从总数中删除确切的类。
我想得到的班级和部分出席没有提交在特定日期。如果有任何功能可在laravel或查询得到所需的结果。

***正如要求进一步解释的那样,问题P.S.中包含了班级和部门表。我想进一步解释一下为什么我从学生表而不是班级和部门表中获取班级。班级表中可能有一些空班级,一些班级可能有5个(A,B,C,D,E)节,但有些可能有2(A,B)或3节。所以我将类名和节保存在学生表中&直接从学生表加载类。
类别表

public function up()
{
    Schema::create('class', function (Blueprint $table) {
        $table->Increments('id');
        $table->string('name', 50);
        $table->string('full_name', 50);
        $table->boolean('status')->default(1);
        $table->timestamps();        
    });
}

章节表

public function up()

    {
        Schema::create('sections', function (Blueprint $table) {
            $table->integer('id',true,true);
            $table->string('name', 50);
            $table->string('short_name', 50); 
            $table->boolean('status')->default(1);
            $table->timestamps();
        });
    }
new9mtju

new9mtju1#

既然你对在数据库层正确地做这件事不感兴趣,就用array_udiff()来比较这两个数组吧,我对Laravel不是很熟悉,所以我假设$classAll$posted是对象数组:

$pending = array_udiff($classAll, $posted, function($a, $b) {
    if (
        $a->clas_name === $b->clas_name &&
        $a->section_name === $b->section_name
    ) {
        return 0;
    } else {
        return -1;
    }
});

我把我以前的答案留在这里,因为它仍然显示了一个更好的方案。
由于您的问题中没有包括classessections表,因此假定您具有:

  • 类(ID、名称)
  • 节(ID,名称,类ID)

获取指定日期内未提交出勤率的课程/部门的一种方法是:

SELECT
    c.name AS clas_name,
    s.name AS section_name
FROM classes c
JOIN sections s ON c.id = s.class_id
WHERE NOT EXISTS (
        SELECT 1
        FROM attendance_dates
        WHERE clas_name = c.name
        AND section_name = s.name
        AND date = :specific_date
)
ORDER BY clas_name, section_name;

使用Laravel的查询构建器,它应该是这样的:

$classesNotSubmitted = DB::table('classes c')
    ->join('sections s', 'c.id', '=', 's.class_id')
    ->select('c.name clas_name', 's.name section_name')
    ->whereNotExists(function($query) {
            $query->selectRaw(1)
                  ->from('attendance_dates')
                  ->whereRaw('clas_name = c.name')
                  ->whereRaw('section_name = s.name')
                  ->where('date', $date)
        })
    ->orderBy('clas_name', 'ASC')
    ->orderBy('section_name', 'ASC')
    ->get();

如果您想获得课程/部门的完整列表,以及是否提交了给定日期的出席情况,您可以将子查询移动到SELECT列表中:

SELECT
    c.name AS clas_name,
    s.name AS section_name,
    EXISTS (
        SELECT 1
        FROM attendance_dates
        WHERE clas_name = c.name
        AND section_name = s.name
        AND date = :specific_date
    ) AS att_taken
FROM classes c
JOIN sections s ON c.id = s.class_id
ORDER BY clas_name, section_name;

使用Laravel的查询生成器:

$classesAll = DB::table('classes c')
    ->join('sections s', 'c.id', '=', 's.class_id')
    ->selectRaw('c.name clas_name, s.name section_name, EXISTS (
                                        SELECT 1
                                        FROM attendance_dates
                                        WHERE clas_name = c.name
                                        AND section_name = s.name
                                        AND date = ?) AS att_taken', [$date])
    ->orderBy('class_name', 'ASC')
    ->orderBy('section_name', 'ASC')
    ->get();

我不是一个Laravel用户,这些还没有经过测试,所以可能需要调整,让他们的工作。

hjzp0vay

hjzp0vay2#

我认为您可以运行一个查询来获取attendence_date表中某个日期内不存在的所有课程名称。

SELECT *
FROM students
WHERE clas_name NOT IN (
    SELECT clas_name
    FROM attendance_date
    WHERE date = <your date>
);

相关问题