将四个查询合并为一个

时间:2014-09-29 14:47:22

标签: mysql sql

我继承了遗留代码库和带有它的数据库(我无法修改),并且在重构代码时我遇到了这些查询。如果可能的话,我试图将4个单独的查询放在一个查询中。如果需要,我将提供表模式。另外,如果您认为在一个查询中无法解决,请详细说明。

这些是查询(关于体育),最终目的是获取给定用户创建和/或加入的所有杯子

  • cups table包含创建的杯子,他们的创建者等
  • join table保存已加入特定杯子的用户,他们已结束的地点(等级)
  • registered_cups表保存杯子的名称

第一个尝试获取用户创建的所有杯子

SELECT cup_id FROM cups WHERE user_id = 'givenUser' AND cup_type <> 6

第二个是试图获得用户加入的所有杯子

SELECT joined.cup_id, joined.cup_rank FROM joined LEFT JOIN cups USING (cup_id) WHERE joined.user_id = 'givenUser' AND cups.cup_type <> 6

现在,将第一个结果放入以逗号分隔的字符串中,然后将其提供给下一个查询。第三个是阅读所选杯子的信息

SELECT cup_id, user_id, status FROM joined WHERE cup_id IN (cupList)

最后一个获得杯子的名称,他们的版本,并命令他们

SELECT name, cup_id, edition, cups.user_id FROM cups LEFT JOIN registered_cups USING(register_id) WHERE cup_id IN (cupList) ORDER BY name ASC, edition DESC

正如你所看到的那样,有很多重复,而不是需要的东西,所以这就是我想出来的:

SELECT cups.cup_id, cups.edition, cups.user_id, joined.cup_rank, registered_cups.name
FROM cups, joined, registered_cups
WHERE cups.cup_id = joined.cup_id
AND cups.register_id = registered_cups.register_id
AND joined.user_id = '308288'
AND cups.cup_type <>6
ORDER BY registered_cups.name ASC , cups.edition DESC 

我的查询问题是我只获得了用户加入的杯子,但也有可能用户创建了一个杯子,但没有参与其中。这就是为什么前两个查询,但我不知道如何成功地组合它们。我希望你明白我想要实现的目标。

更新

这是一个带有一点输入的架构的fiddle。有问题的用户是user_id = 133,它应该基本上选择所有的行,即21,其中一个应该是有组织的杯子,但是没有被用户加入,所有其他都是

2 个答案:

答案 0 :(得分:1)

有几种方法可以做到。你可以这样做一个外连接:

SELECT cups.cup_id, cups.edition, cups.user_id, joined.cup_rank, registered_cups.name
  FROM cups INNER JOIN registered_cups ON cups.register_id = registered_cups.register_id
       LEFT OUT JOIN joined ON cups.cup_id = joined.cup_id and joined.user_id = '308288'
 WHERE cups.cup_type <>6
   AND (joined.user_id IS NOT NULL
    OR cups.user_id = '308288')
 ORDER BY registered_cups.name ASC , cups.edition DESC 

或像这样的工会:

SELECT cups.cup_id, cups.edition, cups.user_id, joined.cup_rank, registered_cups.name
  FROM cups, joined, registered_cups
 WHERE cups.cup_id = joined.cup_id
   AND cups.register_id = registered_cups.register_id
   AND joined.user_id = '308288'
   AND cups.cup_type <>6
 UNION
SELECT cups.cup_id, cups.edition, cups.user_id, null, registered_cups.name
  FROM cups, registered_cups
 WHERE cups.register_id = registered_cups.register_id
   AND cups.user_id = '308288'
   AND cups.cup_type <>6
   AND NOT EXISTS 
       (SELECT 1 
          FROM joined 
         WHERE cups.user_id = joined.user_id and cups.cup_id = join.cup_id)
 ORDER BY registered_cups.name ASC , cups.edition DESC 

答案 1 :(得分:1)

我假设您有一个用户表,并且在它们可以加入之前创建了杯子(似乎是逻辑)

SELECT
    c.cup_id,
    u.user_name,
    c.edition,
    j.status,
    j.cup_rank,
    cr.user_id IS NOT NULL created,
    r.name
FROM
    (SELECT 133 user_id) u
/* semi cross join the cups table */
JOIN
    cups c
    ON u.user_id = 133 AND c.cup_type <> 6
JOIN
    registered_cups r
    ON c.register_id = r.register_id
LEFT JOIN
    joined j
    ON c.cup_id = j.cup_id AND u.user_id = j.user_id
LEFT JOIN
    cups cr
    ON c.cup_id = cr.cup_id AND u.user_id = cr.user_id
ORDER BY r.name, c.edition

也许我有一些列名错误或错误的表,但想法保持不变

编辑: SQL Fiddle