2013-04-16 3 views
0

Я работаю над сайтом инвентаризации видеоигр. Вот упрощенная версия моих таблиц базы данных вместе с некоторыми данными выборки:SQL Left Присоединиться к графу

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 Nintendo игры (Super Mario Bros.), 2 Супер Нинтендо игры (Super Mario World и Super Mario Kart) и 0 игр Nintendo 64. У jane_doe есть 1 игра Nintendo (Super Mario Bros. 2), 0 игр Super Nintendo и 0 игр Nintendo 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

Это близко ... но он не показывает Nintendo 64 с 0 играми. Спасибо за ваше время! – Nick

+0

@summea Да, но john_doe не владеет ни одним из них. – Nick

Смежные вопросы