将标签和级别存储在两个表中,需要获取作为列返回的级别的标记

时间:2011-03-20 15:15:41

标签: mysql

你好 我有一个选择查询的问题

有一张桌子:

tag_hierarhy
--------------------
|id    |parent_id  |
--------------------
|1     |0          |
|2     |1          |
|3     |1          |
|3     |2          |
|4     |1          |
|4     |2          |
|4     |3          |
|5     |1          |
|5     |2          |
|5     |3          |
--------------------
Comment:
id        - this is the column with tag id
parent_id - this is the id of the tag that is parent of tag with id from column id
One tag can belong to many parents for example: tag 5 belongs to tag 1 and 2 and 3

我有另一张表,其中我保留了标签的级别。

tag_level
--------------------
|id      |level    |
--------------------
|1       |0        |
|2       |1        |
|3       |2        |
|4       |3        |
|5       |3        |
--------------------
Comment:
id    - this is the tag id
level - this is the tag level in hierarhy
0 - continent level,
1 - country level,
2 - region in country level,
3 - city or village in level 2

现在我必须在一行中查看一个标签。例如,对于id = 5的标签,我想获得一行包含以下数据:

-------------------------------------------
| tid | l0_tid | l1_tid | l2_tid | l3_tid |
-------------------------------------------
| 5   | 1      | 2      | 3      | NULL   |
-------------------------------------------
Comment:
tid - the id of requested tag
l0_tid - the id of the tag that tag with id=5 belongs to. This tag must be on level=0
l1_tid - the id of the tag that tag with id=5 belongs to. This tag must be on level=1
l2_tid - the id of the tag that tag with id=5 belongs to. This tag must be on level=2
l3_tid - the id of the tag that tag with id=5 belongs to. Thie tag must be on level=3
Imagine for Example tag 5 is pointing to 'Berlin' so:
l0_tid must point to tag 'Europe',
l1_tid must point to tag 'Germany'... and so on

由于许多性能原因,我无法更改此结构。任何人都可以帮我查询mysql,它能够以我描述的方式获取数据吗?我整天都在为此而战,我的思绪一片空白。我不希望子查询只加入。我正在寻求帮助。感谢。

表格的结构:

CREATE TABLE  `street_traveler`.`tag_hierarhy` (
  `id` int(11) unsigned NOT NULL,
  `parent_id` int(11) unsigned NOT NULL,
  UNIQUE KEY `id_parent_id` (`id`,`parent_id`)
) ENGINE=MyISAM


CREATE TABLE  `street_traveler`.`tag_level` (
  `id` int(11) unsigned NOT NULL,
  `level` int(11) unsigned NOT NULL,
  UNIQUE KEY `id_level` (`id`,`level`)
) ENGINE=MyISAM

1 个答案:

答案 0 :(得分:1)

尝试这样的事情:

SELECT t.id                       AS tid, 
       GROUP_CONCAT(d0.parent_id) AS l0_tid, 
       GROUP_CONCAT(d1.parent_id) AS l1_tid, 
       GROUP_CONCAT(d2.parent_id) AS l2_tid, 
       GROUP_CONCAT(d3.parent_id) AS l3_tid 
FROM   tag_level t 
       LEFT JOIN (SELECT th1.id, 
                         th1.parent_id 
                  FROM   tag_hierarhy th1 
                         JOIN tag_level t1 
                           ON t1.id = th1.parent_id 
                  WHERE  level = 0 
                  GROUP  BY th1.id) d0 
         ON d0.id = t.id 
       LEFT JOIN (SELECT th2.id, 
                         th2.parent_id 
                  FROM   tag_hierarhy th2 
                         JOIN tag_level t2 
                           ON t2.id = th2.parent_id 
                  WHERE  level = 1 
                  GROUP  BY th2.id) d1 
         ON d1.id = t.id 
       LEFT JOIN (SELECT th3.id, 
                         th3.parent_id 
                  FROM   tag_hierarhy th3 
                         JOIN tag_level t3 
                           ON t3.id = th3.parent_id 
                  WHERE  level = 2 
                  GROUP  BY th3.id) d2 
         ON d2.id = t.id 
       LEFT JOIN (SELECT th4.id, 
                         th4.parent_id 
                  FROM   tag_hierarhy th4 
                         JOIN tag_level t4 
                           ON t4.id = th4.parent_id 
                  WHERE  level = 3 
                  GROUP  BY th4.id) d3 
         ON d3.id = t.id 
GROUP  BY t.id 

返回:

+---+------+------+------+------+
| 1 | NULL | NULL | NULL | NULL |
| 2 | 1    | NULL | NULL | NULL |
| 3 | 1    | 2    | NULL | NULL |
| 4 | 1    | 2    | 3    | NULL |
| 5 | 1    | 2    | 3    | NULL |
+---+------+------+------+------+

您需要拥有索引

  • (tag_level.id,tag_level.level)
  • (tag_hierarchy.id,tag_hierarchy.parent_id)