【问题标题】:MySQL Query to recursively obtain entries based on parentIDMySQL Query 根据 parentID 递归获取条目
【发布时间】:2017-06-30 06:07:29
【问题描述】:

对于这个例子,我们有四个表。

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

此查询的目标是获得一个包含单个游戏的时间表,然后根据游戏行中的 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 与三场比赛相关:

Super Mario Bros 和 Crazy Kong 与数据直接相关,parent 设置为 (1)Mario Sunshine 与游戏 ID (1) 间接相关,因为它的父级设置为 Super Mario Bros @987654330 @

另一个 ID 为 (5) 且难度 ID 为 1 的游戏有一个与之相关的游戏,即 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'
  ]

【问题讨论】:

    标签: mysql


    【解决方案1】:

    最多 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;
    

    【讨论】:

    • 不幸的是我不能硬核这个,因为它预计会进入无限深的层次。
    • 这可能真的很复杂。我希望this 类似的例子会有所帮助。
    • 目前,这将起作用,因为我们不会深入几个级别,但是当使用多个设备时,您的查询中会出现错误,请参阅此示例:sqlfiddle.com/#!9/61b0e/2 你可以尝试修复它吗?行显示两次。
    【解决方案2】:

    一种可能性

    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

    【讨论】:

    • 这不会返回应该返回的Mario Sunshine,因为它的父 id 是 2,这是一个父 id 为 1 的游戏。它应该无限深。时间表返回游戏 id 1。游戏 2 和 3 链接到 1。游戏 4 链接到 2。所以它也应该返回。
    • 我没有明白你的意思。为什么要退回父母 id 为 2 的游戏?因为 Mario Bros 的 id = 1 , Super Mario Bros 的 parent id = 1 , Crazy Kong 的 parent id = 1 。 parent id = 2 如何出现在图片中?您能解释一下要求吗?您是否正在寻找类似将父 ID 链接到顶层的东西?
    • 这就是我所说的“递归”,将其视为一个层次结构,其中 1 位于顶部。把他们想象成母亲、女儿和他们的孩子。 (1) -> (2, 3) -> (4) 游戏 id 4“Mario Sunshine”应该显示,因为它是游戏 id 2 的“女儿”。
    • 是的,我现在明白你的意思了。你正在寻找父母的第 n 个(最后一个)孩子。递归
    • 没错。 @doriclazar 的答案产生了正确的结果,但它不是递归的
    猜你喜欢
    • 1970-01-01
    • 2015-10-21
    • 2015-12-18
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 2015-08-12
    • 2021-05-19
    相关资源
    最近更新 更多