0

我创建了一个页面,我可以在其中查看学生对宿舍的申请。您可以在以下位置进行预览:http: //formularz.funpic.de/dormitory.htm。我正在寻求帮助编写查询以获取页面上显示的信息。房间应该先给贫困学生,然后再给远离宿舍的学生。我有 3 个宿舍:“lubel”、“mleczko”、“maryks”

我当前的数据库查询如下所示:

SELECT * 
  FROM aplication 
  WHERE (sex='w' AND preference1='lubel') 
  GROUP BY poor DESC, distance DESC 
UNION ALL SELECT * 
  FROM aplication 
  WHERE (sex='w' AND preference2='lubel' AND poor='') 
  GROUP BY distance DESC  
UNION ALL SELECT * 
  FROM aplication 
  WHERE (sex='w' AND preference3='lubel' AND poor='') 
  GROUP BY distance DESC

我想为此查询添加限制:

  • 用于润滑油:12 处
  • 为mleczko:13个地方
  • 玛丽克斯:5个地方

如何编写查询以获得这样的结果?我知道我可以LIMIT用来限制结果的数量,但是有什么方法可以确保结果没有冗余?

4

1 回答 1

1

您可以通过将它们(preference1, preference2, preference3)分成单独的表来使这变得非常容易——我们称之为“规范化”。

如果可能,您应该创建类似以下的表:

CREATE TABLE application (application_id ... PRIMARY KEY, sex ..., poor ...);
CREATE TABLE preference (application_id ..., dorm ..., rank ...);

现在,对于每个表格,您将在表格application中拥有三行:一行与,一行与,另一行与。preferencerank = 1rank = 2rank = 3

您可能无法永久更改结构,在这种情况下,您可以使用 临时做同样的事情TEMPORARY TABLE

CREATE TEMPORARY TABLE preference (...)
INSERT INTO preference (SELECT application_id, preference1, 1 FROM application);
INSERT INTO preference (SELECT application_id, preference2, 2 FROM application);
INSERT INTO preference (SELECT application_id, preference3, 3 FROM application);

有了这些,查询就很简单了:

SELECT application.*
FROM application
INNER JOIN preference ON (preference.application_id = application.application_id)
WHERE sex = 'w' AND dorm='lubel' AND poor=''
ORDER BY rank, poor DESC, distance DESC
LIMIT 12

但你要求的远不止这些:实际上一次对每个人进行分类。

为此,我建议添加一个新assignment列(如果需要,这可以临时完成),因此您可以使用一系列四个查询:

UPDATE application SET assignment = NULL

UPDATE application.*
INNER JOIN preference ON (preference.application_id = application.application_id)
SET assignment = 'lubel'
WHERE assignment IS NULL AND sex = 'w' AND dorm='lubel' AND poor=''
ORDER BY rank, poor DESC, distance DESC
LIMIT 12

UPDATE application.*
INNER JOIN preference ON (preference.application_id = application.application_id)
SET assignment = 'mleczko'
WHERE assignment IS NULL AND sex = 'w' AND dorm='mleczko' AND poor=''
ORDER BY rank, poor DESC, distance DESC
LIMIT 13

UPDATE application.*
INNER JOIN preference ON (preference.application_id = application.application_id)
SET assignment = 'maryks'
WHERE assignment IS NULL AND sex = 'w' AND dorm='maryks' AND poor=''
ORDER BY rank, poor DESC, distance DESC
LIMIT 5

请注意,每次您只找到尚未分配任务的人时,因此一旦有人得到他们的选择,分配列就会被填充,并且他们不会匹配任何未来的查询。

我假设任何人都可以获得任何宿舍(即,每个人都偏好所有三个宿舍;这只是这些偏好的顺序问题)。

于 2012-07-07T19:51:09.370 回答