2017-02-12 42 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