MySQL Query需要多个连接

时间:2015-03-24 11:54:02

标签: mysql

我有一个用于记录孩子的系统'他们的行为。如果孩子顽皮,则将其记录为否定,如果它具有良好的行为,则记录为肯定。

例如 - 如果一个孩子粗鲁,那就得到一个粗鲁的'否定,这将在负x点的系统中记录。

我的结构可以在这个sqlfiddle中看到 - http://sqlfiddle.com/#!9/46904

users_rewards_logged表中,reward_id列是链接到扣除OR成就表的外键,具体取决于列的类型。 如果类型为1是扣除奖励,则如果类型值为2,则成就奖励

我基本上想要一个查询来列出这样的内容:

  +------------------------------+
  |   reward   | points  | count |
  +------------------------------+
  | Good Work  |   100   |   1   |
  |    Rude    |   -50   |   2   |
  +------------------------------+

所以它统计数字并根据类型匹配奖励(1是扣除,2是成就)

基于sqlfiddle?

,有什么好办法可以做到这一点?

3 个答案:

答案 0 :(得分:1)

虽然eggyal是正确的 - 这对你的数据来说是相当糟糕的设计 - 你可以做什么,但需要一个UNION条款:

    SELECT users_achievements.name, users_rewards_logged.points, COUNT(*)
    FROM users_rewards_logged
    INNER JOIN users_achievements ON users_achievements.achievement_id = users_rewards_logged.reward_id
WHERE users_rewards_logged.type = 2
    UNION
    SELECT users_deductions.name, users_rewards_logged.points, COUNT(*)
    FROM users_rewards_logged
    INNER JOIN users_deductions ON users_deductions.deduction_id = users_rewards_logged.reward_id
WHERE users_rewards_logged.type = 1
    GROUP BY 1, 2

没有理由不组合成就和扣除表,只使用非冲突的代码。如果组合表,那么您将不再需要UNION子句 - 您的查询将更加简单。

答案 1 :(得分:1)

我注意到你有两个表(users_deductionsusers_achievements)来定义奖励的类型。正如@eggyal所说,你违反了正交设计的原则,这导致你的模式缺乏规范化。

因此,我已将表users_deductionsusers_achievements合并到一个名为reward_type的表中。

结果就是这个小提琴:http://sqlfiddle.com/#!9/813d5/6

答案 2 :(得分:1)

这是一个获得上述预期结果的查询:

SELECT COALESCE(ua.name, ud.name) AS reward,
  SUM(url.points) AS points, COUNT(url.logged_id) AS count
FROM users_rewards_logged url
LEFT JOIN users_deductions ud
  ON ud.deduction_id = url.reward_id
  AND url.type = 1
LEFT JOIN users_achievements ua
  ON ua.achievement_id = url.reward_id
  AND url.type = 2
GROUP BY url.reward_id, url.type

您的SQLFiddle按表points的错误顺序排列typeusers_rewards_logged

以下是带有结果的固定SQLFiddle

reward      points  count
Good Work      100      1
Rude           -50      2