如何 SQL 选择一对多关系并合并输出
Posted
技术标签:
【中文标题】如何 SQL 选择一对多关系并合并输出【英文标题】:How to SQL Select a one to many relation and merge the output 【发布时间】:2012-02-07 11:31:59 【问题描述】:自从我接近解决方案后,这已经大大更新了
我想标题不是最好的,但我不知道如何更好地解释它。
我在两个相关表格中有坐标位置。表locations(id, name, description, created_at)
和locations_coordinates(location_id, lat, lng, coordinates_order)
。
我正在存储未知数量的坐标(一个多边形),这就是我使用两个表的原因。
现在我正在运行以下查询
SELECT l.id,
l.name,
l.description,
l.created_at,
GROUP_CONCAT(Concat(c.lat, ":", c.lng) ORDER BY c.coordinate_order ASC
SEPARATOR
', ') AS coordinates
FROM locations l
LEFT JOIN locations_coordinates c
ON l.id = c.location_id
WHERE l.id = ' . $id . '
GROUP BY l.id,
l.name,
l.description,
l.created_at ASC
所以我得到以下输出(使用 id = 3):
[
"id":"3",
"name":"Stadthalle",
"description":"Die Wiener Stadthalle",
"created_at":"2012-01-07 14:22:06",
"coordinates":"48.201187:16.334213, 48.200665:16.331606, 48.202989:16.331091, 48.203075:16.334192"
]
我想得到的是纬度和经度对,比如:
[
"id":"3",
"name":"Stadthalle",
"description":"Die Wiener Stadthalle",
"created_at":"2012-01-07 14:22:06",
"coordinates":[
[
"48.201187,16.334213"
],
[
"48.200665,16.331606"
],
[
"48.202989,16.331091"
],
[
"48.203075,16.334192"
]
]
]
所以我的问题是:有没有办法只使用 SQL 获得所需的输出?如果没有,是否可以改进我的查询,以便我更轻松地使用应用程序代码(对我来说是 php)?
更新:
我正在使用MyISAM,在“locations_coordinates”表中,“locations_id”和“coordinates_order”是PRIMARY,“coordinates_order”设置为AUTO INCREMENT,因此它在插入时总是开始一系列新的订单号。 (我需要这个,所以我可以稍后按正确的顺序选择坐标)。
【问题讨论】:
【参考方案1】:只要您设置外键(如果需要,可以设置多个),但请确保为键编制索引以获得更快的速度。
然后确保您可以像上面提到的那样进行多个连接,只要位置和坐标具有外键 user.id
实际上几天前我回答了一个类似的问题(很有趣,它与位置/坐标有关),不幸的是我今晚无法点击任何链接来转发你,也许浏览我的个人资料。
【讨论】:
我正在使用 MyISAM,在“locations_coordinates”表中,“locations_id”和“coordinates_order”是主要的,“coordinates_order”设置为自动增量,所以它总是开始一系列新的订单号插入时。 (我需要这个,所以我可以稍后以正确的顺序选择坐标)。我不确定您所说的 user.id 是什么意思?【参考方案2】:我是这样解决类似问题的:
首先,获取我需要的所有位置记录,将它们放入以 ID 为键的哈希映射中。
其次,获取位置记录id中location_id所在的所有坐标记录。 可能:select * from coordinate where location_id in (?, ?, ...)
第三,迭代坐标记录,将lat和lng列设置到对应的位置记录中。
如果位置记录的大小不太大,只需要两条SQL语句。因此,我们获得了更好的性能。
【讨论】:
以上是关于如何 SQL 选择一对多关系并合并输出的主要内容,如果未能解决你的问题,请参考以下文章