2013-04-16 69 views
0

我正在研究视频游戏库存网站。这里是我的数据库表的简化版本,一些样本数据一起:SQL左加入计数

CREATE TABLE `platforms` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(16) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; 

INSERT INTO `platforms` VALUES(1, 'Nintendo'); 
INSERT INTO `platforms` VALUES(2, 'Super Nintendo'); 
INSERT INTO `platforms` VALUES(3, 'Nintendo 64'); 

-- 

CREATE TABLE `games` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `platform_id` int(10) unsigned NOT NULL, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ; 

INSERT INTO `games` VALUES(1, 1, 'Super Mario Bros.'); 
INSERT INTO `games` VALUES(2, 1, 'Super Mario Bros. 2'); 
INSERT INTO `games` VALUES(3, 2, 'Super Mario World'); 
INSERT INTO `games` VALUES(4, 2, 'Super Mario Kart'); 
INSERT INTO `games` VALUES(5, 3, 'Super Mario 64'); 
INSERT INTO `games` VALUES(6, 3, 'Mario Kart 64'); 

-- 

CREATE TABLE `users` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `username` varchar(64) NOT NULL, 
    `password` varchar(64) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; 

INSERT INTO `users` VALUES(1, 'john_doe', '$2a$10$cQhc4VAXVMEyC1tA.VRoWunpNVi7392adacT/weVBzu6XGI6.Jx/K'); 
INSERT INTO `users` VALUES(2, 'jane_doe', '$2a$10$Ot2BmlT14hKDxHGIV8jBx.lW76HCWdwuOhNGIYrJO5O7BEtDUWLWu'); 

-- 

CREATE TABLE `games_users` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `game_id` int(10) unsigned NOT NULL, 
    `user_id` int(10) unsigned NOT NULL, 
    `created` datetime NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ; 

INSERT INTO `games_users` VALUES(1, 1, 1, '2013-04-12 12:18:09'); 
INSERT INTO `games_users` VALUES(2, 3, 1, '2013-04-12 12:18:42'); 
INSERT INTO `games_users` VALUES(3, 4, 1, '2013-04-12 12:19:13'); 
INSERT INTO `games_users` VALUES(4, 2, 2, '2013-04-12 12:19:32'); 

正如你所看到的,john_doe即有1级任天堂的游戏(超级马里奥兄弟),2个超级任天堂游戏(超级马里奥世界和超级马里奥卡丁车)和0个任天堂64游戏。 jane_doe有1个任天堂游戏(超级马里奥兄弟2),0个超级任天堂游戏和0个任天堂64游戏。

我想编写一个特定于查询用户的查询,列出所有控制台,并列出用户对每个控制台的游戏数量。

这就是结果会是什么john_doe即:

platform.id: 1 
platform.name: Nintendo 
game_count: 1 

platform.id: 2 
platform.name: Super Nintendo 
game_count: 2 

platform.id: 3 
platform.name: Nintendo 64 
game_count: 0 

这就是结果会是什么jane_doe:

platform.id: 1 
platform.name: Nintendo 
game_count: 1 

platform.id: 2 
platform.name: Super Nintendo 
game_count: 0 

platform.id: 3 
platform.name: Nintendo 64 
game_count: 0 

我怎样才能做到这一点?

+1

你甚至想什么......? –

+0

@HmxaMughal我不知道从哪里开始。对不起,我不是很好 – Nick

回答

3
SELECT p.id, p.name, IFNULL(t.cnt, 0) 
FROM platforms p 
LEFT JOIN (
    SELECT g.platform_id as 'id', COUNT(g.id) as cnt 
    FROM users u 
    JOIN games_users gu ON gu.user_id = u.id 
    JOIN games g ON g.id = gu.game_id 
    WHERE u.username = "jane_doe" 
    GROUP BY g.platform_id 
) t ON t.id = p.id 

DEMO

+0

钉钉!非常感谢! – Nick

0
SELECT p.id, p.name, COUNT(g.id) FROM users u 
LEFT JOIN games_users gu ON u.id = gu.user_id 
LEFT JOIN games g ON g.id = gu.game_id 
LEFT JOIN platforms p ON g.platform_id = p.id 
WHERE u.id = 1 
GROUP BY p.id 

http://sqlfiddle.com/#!2/6104d/6

如果你想看到0的,你必须做一些作弊我想,这是我如何实现它。我得到了user_id的总和(因为它们都是相同的)并被user_id分隔。

SELECT p.id, p.name, IFNULL(SUM(user_id),0)/1 FROM platforms p 
LEFT JOIN games g ON g.platform_id = p.id 
LEFT JOIN games_users gu ON g.id = gu.game_id AND gu.user_id = 1 
GROUP BY p.id, p.name 


SELECT p.id, p.name, IFNULL(SUM(user_id),0)/2 FROM platforms p 
LEFT JOIN games g ON g.platform_id = p.id 
LEFT JOIN games_users gu ON g.id = gu.game_id AND gu.user_id = 2 
GROUP BY p.id, p.name 
+0

这很接近......但它没有显示任天堂64与0游戏。谢谢你的时间! – Nick

+0

@summea是的,但john_doe不拥有任何一个。 – Nick