具有嵌套/层次关系表的SQL查询

时间:2017-12-17 04:28:54

标签: php mysql hierarchical-data

我有这两个表:

Table "items":
╔════╦══════════════╦═══════╗
║ ID ║     NAME     ║ TYPE  ║
╠════╬══════════════╬═══════╣
║  1 ║ Home         ║ House ║
║  2 ║ Livingroom   ║ Room  ║
║  3 ║ Kitchen      ║ Room  ║
║  4 ║ Pots         ║ Item  ║
║  5 ║ Pans         ║ Item  ║
║  6 ║ Table        ║ Item  ║
║  7 ║ Away         ║ House ║
╚════╩══════════════╩═══════╝

Table "relationships":
╔════╦═══════════╦═══════════╗
║ ID ║  ITEM_ID  ║ PARENT_ID ║
╠════╬═══════════╬═══════════╣
║  1 ║     2     ║     1     ║
║  2 ║     3     ║     1     ║
║  3 ║     4     ║     3     ║
║  4 ║     5     ║     3     ║
║  5 ║     6     ║     2     ║
╚════╩═══════════╩═══════════╝

我正在php中构建以下数组:

$arr = array( 
  '1' => array(
    'name' => 'Home',
    'rooms' => array(
      '2' => array(
        'name' => 'livingroom',
        'items' => array(
          '6' => 'Table'
        )
      ),
      '3' => array(
        'name' => 'kitchen',
        'items' => array(
          '4' => 'Pots',
          '5' => 'Pans'
        )
      ),
    ),
  );
  '7' => array(
    'name' => 'Away',
    'rooms' => array(
    ),
  );
);

目前,这样做的方法是首先对房屋的物品表进行查询:

SELECT
  id,
  name
FROM items
WHERE type = "House"';

然后对左边的关系表进行查询,将item_id上的items表连接起来,以获取名称和类型。

SELECT
  i.id        AS id,
  i.name      AS name,
  i.type      AS type,
  r.parent_id AS parent
FROM relationships r
LEFT JOIN items i
ON r.element_id = i.id';

最后使用三个foreach循环来构建数组。一个是从第一个查询构建房屋。然后是另一个将房间和物品分开,第三个将它们全部组合成最终的阵列。

虽然它有效,但我确信查询可以提供更好的解决方案,例如将两者合二为一。如何将这个查询合并为一个,并使用尽可能少的循环构建数组?

1 个答案:

答案 0 :(得分:0)

如果您只有3个嵌套级别,则此查询将用于返回父级及其子级:

SELECT 
    a.`ID`,
    a.`NAME`,
    a.`TYPE`,
    c.`NAME`,
    c.`TYPE`,
    e.`NAME`,
    e.`TYPE`    
FROM `items` a
JOIN `relationships` b
ON a.`ID` = b.`ITEM_ID`
JOIN `items` c
ON b.`PARENT_ID` = c.`ID`
JOIN `relationships` d
ON b.`PARENT_ID` = d.`ITEM_ID`
JOIN `items` e
ON d.`PARENT_ID` = e.`ID`;