我有三张桌子。一个表叫做places
,这个表包含不同的地方(例如商家,餐馆等......)每个地方"地点"链接到一个名为categories
的表,但是某些类别具有分层结构的子类别(即泰国食品是餐馆的子类别)。该系统允许管理员创建场所并将其与相应的类别或子类别进行匹配。
我想知道的是获得这些关系的最佳方式是什么?目前我正在使用JOIN和GROUP_CONCAT,但我仍然没有得到一个好的结果集。
这些是我的表格:
地方:
+----+----------------+
| id | name |
+----+----------------+
| 1 | Mings Place |
+----+----------------+
| 2 | Halsey Library |
+----+----------------+
| 3 | Stellas USO |
+----+----------------+
places_categories_rel :
+----------+-------------+
| place_id | category_id |
+----------+-------------+
| 1 | 2 |
+----------+-------------+
| 2 | 4 |
+----------+-------------+
| 3 | 3 |
+----------+-------------+
| 3 | 4 |
+----------+-------------+
类别:
+----+-----------+------------+
| id | parent_id | name |
+----+-----------+------------+
| 1 | null | Restaurant |
+----+-----------+------------+
| 2 | 1 | Thai Food |
+----+-----------+------------+
| 3 | 1 | Italian |
+----+-----------+------------+
| 4 | null | Government |
+----+-----------+------------+
| 5 | 4 | Library |
+----+-----------+------------+
| 6 | 4 | Military |
+----+-----------+------------+
正如您所看到的,某些地方附加到子类别,有些地方直接附加到父类别(没有子类别),有些地方有多个子类别,这些子类别具有不同的父类别。
为了获得我的结果,我尝试了以下SQL:
'SELECT `p`.*,
GROUP_CONCAT(DISTINCT(CONCAT (ca.id, "|", `ca`.`parent_id`, "|", ca.name))) as subcategories,
GROUP_CONCAT(DISTINCT(CONCAT (ca1.id, "|", `ca1`.`parent_id`, "|", ca1.name))) as categories
FROM `places` `p`
LEFT JOIN `places_categories_rel` `rel` ON `rel`.`place_id`=`p`.`id`
LEFT JOIN `categories` `ca` ON `ca`.`id`=`rel`.`category_id`
LEFT JOIN `categories` `ca1` ON `ca1`.`id`=`ca`.`parent_id`
GROUP BY `p`.`id`
但我的结果是将某些类别设置为子类别,反之亦然。
我想要的是有一些类型的结果集可以让我有这样的东西:
array (size=3)
0 =>
array (size=2)
'name' => string 'Mings Place' (length=11)
'categories' =>
array (size=1)
0 =>
array (size=2)
'name' => string 'Restaurant' (length=10)
'subcategories' =>
array (size=1)
0 => string 'Thai Food' (length=9)
1 =>
array (size=2)
'name' => string 'Halsey Library' (length=14)
'categories' =>
array (size=1)
0 =>
array (size=2)
'name' => string 'Government' (length=10)
'subcategories' =>
array (size=1)
0 => string 'Library' (length=7)
2 =>
array (size=2)
'name' => string 'Stellas' (length=7)
'categories' =>
array (size=2)
0 =>
array (size=2)
'name' => string 'Restaurant' (length=10)
'subcategories' =>
array (size=1)
0 => string 'Library' (length=7)
1 =>
array (size=2)
'name' => string 'Government' (length=10)
'subcategories' => null
理想情况下,这将全部创建,以便我可以输入过滤器。例如,如果我只想看到有餐馆类别的地方,或者有意大利食品的政府和子类别的地方......
有人可以帮我解决这个问题吗?
答案 0 :(得分:2)
只要你只有两个级别的类别(例如没有子子类别),那么使用JOIN就可以了。
问题是,您的数据有时会引用父类别,有时会引用子类别。这就是为什么你的结果好坏参与。
为避免混合结果,您可以使用以下内容:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ApiController as ApiCtrl">
{{ApiCtrl.Api.status}} {{ApiCtrl.Api.meta.count}} {{ApiCtrl.Api.data[0].nickname}} {{ApiCtrl.Api.data[0].account_id}}
</div>
<hr>
<div ng-controller="ApiController as ApiCtrl">
<div>
<table>
<thead>
<tr>
<th ng-repeat="(key, value) in ApiCtrl.Api">{{key}}</th>
</tr>
</thead>
<tbody>
<td ng-repeat="(key, value) in ApiCtrl.Api">
{{value}}
</td>
</tbody>
</table>
</div>
</div>
</div>
我不确定这是一个非常有效的选项,但正如您所看到的,您需要将“相关类别作为父母”(c_direct_parent)和“相关类别是儿童”(c_child)分开。
通过这种分离,您现在可以正确检索父母和孩子的数据列表。为清楚起见,我将“...”放入GROUP_CONCAT内部。
答案 1 :(得分:1)
所以这不是一个好方法,但这可能足以让你的问题解决方案
SELECT `p`.*,c.*
FROM `places` `p`
LEFT JOIN `places_categories_rel` `rel` ON `rel`.`place_id`=`p`.`id`
LEFT JOIN (
SELECT c1.id as childID, c1.name ChildName, c2.name as ParentName
from categories c1
LEFT OUTER JOIN categories c2
ON c1.parent_id = c2.id) c on c.childID= rel.category_id
输出: -
id name childID ChildName ParentName
1 Mings Place 2 Thai Food Restaurant
3 Stellas 3 Italian Restaurant
2 Halsey Library 4 Government NULL
3 Stellas 4 Government NULL
现在你必须考虑如何按名称分组。
对此的解决方法是,如果parenty为空,则将其替换为空白字符串,否则使用parentCategory name。
SELECT `p`.*,GROUP_CONCAT(ChildName) as Category,GROUP_CONCAT(if(ParentName IS NULL ," ",ParentName ) ) as parent
FROM `places` `p`
LEFT JOIN `places_categories_rel` `rel` ON `rel`.`place_id`=`p`.`id`
LEFT JOIN (
SELECT c1.id as childID, c1.name ChildName, c2.name as ParentName
from categories c1
LEFT OUTER JOIN categories c2
ON c1.parent_id = c2.id) c on c.childID= rel.category_id
GROUP BY `p`.`id`
生成输出
id name Category parent
1 Mings Place Thai Food Restaurant
2 Halsey Library Government
3 Stellas Italian,Government Restaurant,