我有一个用于记录孩子的系统'他们的行为。如果孩子顽皮,则将其记录为否定,如果它具有良好的行为,则记录为肯定。
例如 - 如果一个孩子粗鲁,那就得到一个粗鲁的'否定,这将在负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?
,有什么好办法可以做到这一点?答案 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_deductions
和users_achievements
)来定义奖励的类型。正如@eggyal所说,你违反了正交设计的原则,这导致你的模式缺乏规范化。
因此,我已将表users_deductions
和users_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
的错误顺序排列type
和users_rewards_logged
。
以下是带有结果的固定SQLFiddle:
reward points count
Good Work 100 1
Rude -50 2