具有多个不同标准的UNION SELECT,其中没有真正的FK

时间:2011-08-21 00:08:54

标签: mysql sql database

我需要从几个表格中选择一个项目,其中包含一个有问题的标准。 有一个meta_data表,其中包含有关引用表的信息。简化结构:

table quest
id   INT AI PK
id_questtype   INT  FK -> questtype.id
id_creator   INT  FK -> user.id
creationdate   DATETIME
...

每个id指的是各自的表

table user
id   INT AI PK
id_group   INT
username   VARCHAR(255)
...

table questtype
id   INT AI PK
name   VARCHAR(100)
...

现在变得棘手:

table  quest_meta
id   INT AI PK
id_quest   INT  FK -> quest.id
id_user   INT  FK -> user.id
id_meta   INT NN
key   VARCHAR(20)
value   LONGTEXT

此表“quest_meta”用于存储每个任务项的各种附加信息。例如问题1,问题2等。

table participation
id_user   INT  FK -> user.id
id_quest   INT  FK -> quest.id
id_quest_meta   INT NN

id_quest_meta引用quest_meta.id_meta,但它不是真正的FK,因为quest_meta表中可能有多个行具有相同的id_meta。

工作一切都很好,直到我想查询信息加入所有这些表并且必须完成!2!参与表中的标准。

我当前的查询看起来像这样:

SELECT up.time, qm.value as title, u.username, u.id as id_user, q.id as id_quest
FROM participation p INNER JOIN quests q 
ON p.id_quest = q.id INNER JOIN user u
ON p.id_user = u.id INNER JOIN quest_meta qm
ON q.id = qm.id_quest
WHERE up.time > '2011-08-19 00:00:00' AND qm.key = 'quest_title' AND qm.id_meta = -1
GROUP BY p.id_user
UNION
SELECT p.time, qm.value as title, u.username, u.id as id_user, q.id as id_quest
FROM participation p INNER JOIN quests q 
ON p.id_quest = uq.id INNER JOIN users u
ON p.id_user = u.id INNER JOIN quests_meta qm
ON q.id = qm.id_quest
WHERE p.time > '2011-08-19 00:00:00' AND q.id = 2 AND p.vote = '1' AND p.id_quest_meta = -7
GROUP BY id_user 
ORDER BY time DESC;

UNION的原因是,我需要额外的标准p.vote ='1' 与p.id_quest_meta = -7一起(这是我知道的quest_meta意味着它应该显示)。 所以这就是我所拥有的......

我现在的问题是:我还能如何确保只选择FROM 2nd SELECT行 在哪里qm.key ='quest_title'和qm.id_quest_meta = -1

目前,我从参与表中的所有行收到一个随机的qm.value。

所有表格都是InnoDB。 如果有任何不清楚的地方,那就无法解释缺少的任何细节。非常感谢。

1 个答案:

答案 0 :(得分:1)

我在一个良好的睡眠中找到了解决方案并梦想着它:)

解决方法是,将第二个SELECT放在没有GROUP BY的子选择中,这允许我从满足标准1的行中选择“WHERE标准2”,然后对结果进行GROUP,并使UNION成为第一个SELECT。

以下是查询:

SELECT up.time, qm.value as title, u.username, u.id as id_user, q.id as id_quest, qm.key as tit
FROM participation p INNER JOIN quests q 
ON p.id_quest = q.id INNER JOIN user u
ON p.id_user = u.id INNER JOIN quest_meta qm
ON q.id = qm.id_quest
WHERE p.time > '2011-08-19 00:00:00' AND qm.key = 'quest_title' AND qm.id_meta = -1
GROUP BY p.id_user
UNION
SELECT a.time, a.type, a.title, a.username, a.id_user, a.id_quest, a.tit
FROM (
SELECT p.time, qm.value as title, u.username, u.id as id_user, q.id as id_quest, qm.tit
FROM participation p INNER JOIN quests q 
ON p.id_quest = uq.id INNER JOIN users u
ON p.id_user = u.id INNER JOIN quests_meta qm
ON q.id = qm.id_quest
WHERE p.time > '2011-08-19 00:00:00' AND q.id = 2 AND p.vote = '1' AND p.id_quest_meta = -7
) AS a
WHERE a.tit = 'quest_title'
GROUP BY id_user 
ORDER BY time DESC;

唯一的缺点是,我不得不在结果表中添加一个列(qm.tit),因为我需要在“select from subselect”(WHERE a.tit ='quest_title')中查询它。