2017-02-12 92 views
1

对于本示例,我们有四个表。MySQL Query以递归方式获取基于parentID的条目

  • 困难
  • 游戏
  • 设备
  • 时刻表

该查询的目标是有包含一个单一的游戏,然后让所有与该游戏的游戏时间表基于游戏行中的ParentID。

下面的JSON数据说明了这一点细节,我相信

/* GAMES */ { 
    id: 1, 
    name: 'Mario Bros', 
    parent: null 
}, { 
    id: 2, 
    name: 'Super Mario Bros', 
    parent: 1 
}, { 
    id: 3, 
    name: 'Crazy Kong', 
    parent: 1 
}, { 
    id: 4, 
    name: 'Mario Sunshine', 
    parent: 2 
}, { 
    id: 5, 
    name: 'Dog Fights', 
    parent: null, 
}, { 
    id: 6, 
    name: 'War Thunder', 
    parent: 5 
}, { 
    id: 7, 
    name: 'Pacman', 
    parent: null 
} 

/* SCHEDULE */ { 
    difficulty: 1, 
    weekday: 1, 
    game: 1 
}, { 
    difficulty: 1, 
    weekday: 1, 
    game: 5 
}, { 
    difficulty: 2, 
    weekday: 1, 
    game: 7 
} 

在这个数据的两场比赛(1, 5)和游戏数据的计划组成,id为(1)游戏中有三场比赛是通过与之相关的parent

超级马里奥兄弟和疯狂的香港具有直接关系到与parent数据被设置为(1)Mario Sunshine是间接相关的游戏ID (1)它的面值耳鼻喉科设置为超级马里奥兄弟(2)

另外一场比赛中与ID (5)其中也有1困难ID有一个游戏涉及到它,这是War Thunder具有父设置为5

有吃豆子一个难度为2,所以它永远不会提出,除非你从时间表中搜索难度2,那么其他6场比赛永远不会出现。

我需要一个查询,可以找到所有相关的游戏基于日程表中的基本条目,这是通过难度id检索所有相关的游戏。

通过像查询返回的游戏:

SELECT ALL RELATED GAMES FROM SCHEDULE WHERE DIFFICULTY = 1 

应该是:

  • 马里奥兄弟
  • 超级马里奥兄弟
  • 疯狂的香港
  • 马里奥阳光
  • 狗战斗
  • 战争雷霆

这里有一个SQLFiddle:http://sqlfiddle.com/#!9/f7583/5

目标是递归地根据表中的所有行的父ID的原始ID的找到所有条目。

关系:

'Mario Bros': [ 
    'Super Mario bros': [ 'Mario Sunshine' ], 
    'Crazy Kong': [], 
], 
'Dog Fights': [ 
    'War Thunder' 
    ] 

回答

0

一种可能性

SELECT schedules.*, games.name 
FROM schedules 
INNER JOIN games ON games.id = schedules.gameId or games.parentId = schedules.gameId 
WHERE schedules.weekday = 1 
AND difficultyId = 1; 

这里是一个工作演示http://sqlfiddle.com/#!9/f7583/57

+0

这不返回'马里奥阳光'应该ret呃,因为它的父母身份是2,这是一个父母身份为1的游戏。它应该深入到无限级别。 计划返回游戏ID 1场和第三场都与1 4场比赛被链接到2所以应该返回为好。 – Hobbyist

+0

我不明白你的意思。为什么应该返回父ID为2的游戏?因为马里奥兄弟的id = 1,超级马里奥兄弟有父母id = 1,而疯狂孔有父母id = 1。 parent id = 2如何进入画面?你能解释一下这个要求吗?你是否在寻找类似于通过父母身份链接链接直到最高层的东西? – mandar

+0

这就是我所说的“递归”,把它看作一个顶层的层次结构。把他们想象为母亲,女儿和他们的孩子。 '(1) - >(2,3) - >(4)'游戏ID 4“马里奥阳光”应显示,因为它是一个游戏ID的“女儿” 2. – Hobbyist

0

多达3个层次:

CREATE TEMPORARY TABLE temp_sc (
id INT NOT NULL, 
gameId INT, 
name VARCHAR(255), 
difficultyId INT, 
weekday INT, 
variation TINYINT(1) default false, 
deviceId INT NOT NULL, 
parentId INT DEFAULT NULL 
); 

INSERT INTO temp_sc (id, gameId, name, difficultyId, weekday, deviceId, parentId) 
SELECT distinct sc.id, g3.id, g3.name, sc.difficultyId, sc.weekday, g3.deviceId, g3.parentId 
FROM schedules as sc 
LEFT JOIN games as g1 ON g1.id = sc.gameId 
LEFT JOIN games as g2 ON g2.parentid = g1.id || g2.id=g1.id 
LEFT JOIN games as g3 ON g3.parentid = g2.id || g3.id=g2.id 
WHERE sc.weekday = 1 
AND sc.difficultyId = 1; 

SELECT temp_sc.name as 'Game Name', temp_sc.gameId as 'Game ID', temp_sc.parentId as 'References ID', dev.name as 'Device' FROM temp_sc 
LEFT JOIN devices as dev ON temp_sc.gameID = dev.id; 
+0

可惜我不能硬核本,因为预计要深入无限的水平。 – Hobbyist

+0

这可能很复杂。我希望[这](http://dba.stackexchange.com/questions/27775/loop-through-self-join-on-table-until-the-operand-column-is-null-completely)类似的例子可以帮助然后。 – doriclazar

+0

就目前而言,这将作为我们不会几个层次深,但有在使用多个设备在您的查询错误,请参阅下面的例子:http://sqlfiddle.com/#!9/61b0e/2能你试图修复它?行显示两次。 – Hobbyist