1

背景

我面临以下与三个表有关的问题

class_sectors表包含三类类

classes表包含学生可以参加的课程列表

class_choices包含学生对每个部门的第一、第二和第三类选择。因此,例如,对于扇区 1,Student_A 将 class_1 作为第一选择,将 class_3 作为第二选择,将 class_10 作为第三选择,然后对于扇区 2,他还有另外三个选择,等等...

class_choices表具有以下列:

kp_choice_id | kf_personID | kf_sectorID | kf_classID | preference | assigned

我认为列名是不言自明的。preference是 1、2 或 3。assigned一旦我们审查了学生的选择并将其分配到班级,它就会被设置为 1。

问题

编写一个 sql 查询,告诉学生他们被分配到每个部门的哪个班级。如果他们的班级没有被分配,它应该默认显示他们的第一偏好。

我实际上已经让这个工作了,但是使用两个(非常臃肿??) sql 查询如下:

$choices = $db -> Q("SELECT
    *, concat_ws(':', `kf_personID`, `kf_sectorID`) AS `concatids`
FROM
    `class_choices`
WHERE
    (`assigned` = '1')
GROUP BY
    `concatids`
ORDER BY
    `kf_personIDID` ASC,
    `kf_sectorID` ASC;");

$choices2 = $db -> Q("SELECT
    *, concat_ws(':', `kf_personID`, `kf_sectorID`) AS `concatids`
FROM
    `class_choices`
WHERE
    `preference` = '1'
GROUP BY
    `concatids`
HAVING
    `concatids` NOT IN (".iimplode($choices).")
ORDER BY
    `kf_personID` ASC,
    `kf_sectorID` ASC;");

if(is_array($choices2)){
    $choices = array_merge($choices,$choices2);
}

现在$choices确实有我想要的。

但我确信有一种方法可以简化这一点,合并两个 SQL 查询,因此它更轻量级。

是否有某种条件 SQL 查询可以做到这一点???

4

1 回答 1

1

您的解决方案使用两个步骤使您能够根据需要过滤数据。由于您正在生成报告,因此这是一种非常好的方法,即使它看起来比您想要的更冗长。

这种方法的优点是更容易调试和维护,这是一大优势。

要改善这种情况,您需要考虑数据结构本身。当我查看class_choices表格时,我看到以下字段:kf_classID, preference, assigned其中包含关键信息。

对于每个班级,该assigned字段为 0(默认)或 1(当为学生分配班级偏好时)。默认情况下,班级preference = 1是分配的班级,因为您在报告assigned=0中显示特定部门中所有学生的班级选择时。

数据模型可以通过强加如下业务规则来改进:
设置preference=1默认值assigned=1。当班级选择过程发生时,如果学生被分配了第二或第三选择,则不分配偏好 1 并分配替代选择。

这意味着应用程序中有更多代码,但它使报告更容易一些。

困难的根源在于分配过程没有明确分配第一偏好。它仅assigned在学生无法获得第一个选择时更新。

总之,您的 SQL 很好,改进来自对数据模型的重新审视。

希望这会有所帮助,并祝工作顺利!

于 2013-03-13T11:18:23.903 回答