我有4个MySQL表:
设计师:id
,name
游戏:id
,name
,designer_id
开始:id
,game_id
完成:id
,game_id
游戏开始时,我的应用向started
添加了一行。游戏结束后,它将向finished
添加一行。我想获得按设计师名称分组的已开始但尚未完成的游戏的总数。这是我到目前为止的内容:
SELECT designer.name, COUNT(started.game_id) AS total FROM started
LEFT JOIN game ON started.game_id = game.id
LEFT JOIN designer ON game.designer_id = designer.id
GROUP BY designer.name
这将使我获得启动游戏的总数,并按其设计师分组。但这并没有考虑到我只想开始而不是结束游戏这一事实。
我试图减去总数,就像这样:
SELECT designer.name, (COUNT(started.game_id) - COUNT(finished.game_id)) AS total
FROM started
LEFT JOIN game ON started.game_id = game.id
LEFT JOIN designer ON game.designer_id = designer.id
LEFT JOIN finished ON finished.game_id = started.game_id
GROUP BY designer.name
尽管开始的游戏比完成的游戏多,但这返回的总数为0
。
示例数据:
设计师
id | name
--------------
1 | Jim Smith
游戏
id | name | designer_id
-----------------------
1 | Test | 1
开始
id | game_id
------------
1 | 1
2 | 1
3 | 1
4 | 1
完成
id | game_id
------------
1 | 1
2 | 1
答案 0 :(得分:1)
首先,我建议更改您的数据库设计,并将启动表和完成表转换为一个,并使用状态字段定义游戏是否完成(这只是您可以忽略所有内容的建议)
这可能对您有帮助:
Select name as dname , count(*) from designer where id in
(Select designer_id from game where id in
(Select started.id from started where started.gameid not in
(Select finished.gameid from finished)))
group by dname
答案 1 :(得分:0)
遵循SQL可能会帮助您
SELECT designer.name, COUNT(started.game_id) AS total
FROM started
LEFT JOIN game ON started.game_id = game.id
LEFT JOIN designer ON game.designer_id = designer.id
LEFT JOIN finished ON finished.game_id = started.game_id
WHERE finished.id IS NULL
GROUP BY designer.name
答案 2 :(得分:0)
如果我正确理解您的工作,则想通过designer.name来了解未完成的游戏数量。您想要这样的东西:
SELECT Games.name, Count(Games.id) AS GamesNotFinished
FROM
(SELECT designer.name, game.id
FROM started
INNER JOIN game ON started.game_id = game.id
LEFT JOIN designer ON game.designer_id = designer.id
LEFT JOIN finished ON finished.game_id = started.game_id
WHERE finished.game_id IS NULL) AS Games
GROUP BY Games.name
在发表评论后,我在Db Fiddler中创建了一个简单的工作示例,表明它确实有效(“ WHERE finish.game_id IS NULL”子句仅显示那些不存在的示例)。请尝试一下在here
中也就是说,回头看表,我很明白为什么您需要两个表来仅管理两个状态。 在游戏表中添加int类型的两列,即“ started”和“ finished”,可能会更好。
然后,您的应用程序可以简单地将启动数设置为1,完成时设置为1,然后您的选择将简单地检查桌面游戏,其中开始数= 1并且完成数= 0,我错了吗?
希望有帮助。
答案 3 :(得分:0)
不存在:
SELECT s.game_id FROM started s
WHERE NOT EXISTS (
SELECT 1 FROM finished
WHERE game_id = s.game_id
)
或具有左联接:
SELECT s.game_id
FROM started s LEFT JOIN finished f
ON f.game_id = s.game_id
WHERE f.id IS NULL
您可以获取所有已开始但尚未完成的游戏ID。
然后,通过仅加入designer
和game
这样的方式,使用上述两个查询中的任何一个来获取所需的结果:
SELECT
d.name,
COUNT(g.id) AS total
FROM designer d INNER JOIN game g
ON d.id = g.designer_id
WHERE g.id IN (
SELECT s.game_id FROM started s
WHERE NOT EXISTS (
SELECT 1 FROM finished
WHERE game_id = s.game_id
)
)
GROUP BY d.id, d.name