Mysql 当前拥有的行上的多对多联接

Mysql 当前拥有的行上的多对多联接,mysql,Mysql,基本上,尝试为locations索引视图编写MySQL查询(可以是任何版本),该视图显示当前与位置关联的所有项。项目位置表代表项目移动的位置和时间 items ______________ | id | name | -------------- | 1 | item1 | | 2 | item2 | | 3 | item3 | | 4 | item4 | -------------- locations ______________ | id | city | --------

基本上,尝试为locations索引视图编写MySQL查询(可以是任何版本),该视图显示当前与位置关联的所有项。项目位置表代表项目移动的位置和时间


items
______________
| id | name  |
--------------
| 1  | item1 |
| 2  | item2 |
| 3  | item3 |
| 4  | item4 |
--------------

locations
______________
| id | city  |
--------------
| 1  | city1 |
| 2  | city2 |
| 3  | city3 |
| 4  | city4 |
--------------

item_location
_______________________________________________________
| id | item_id | location_id | date                   |
------------------------------------------------------|
| 1  | 1       | 1           | 1998-01-01 04:00:00    |
| 2  | 1       | 2           | 1998-01-02 04:00:00    |
| 3  | 2       | 1           | 1998-01-03 04:00:00    |
| 4  | 3       | 1           | 1998-01-04 04:00:00    |
| 4  | 4       | 3           | 1999-01-04 04:00:00    |
| 4  | 4       | 4           | 1999-02-04 04:00:00    |
-------------------------------------------------------

expected output (with limit 3):
____________________________________________________________________________________________
| location.id | location.city | items                                                      |
--------------------------------------------------------------------------------------------
| 1           | city1         | [{"id":"2", "name": "item2"}, {"id":"3", "name": "item3"}] |
| 2           | city2         | [{"id":"1", "name": "item1"}]                              |
| 3           | city3         | [], '', or null because city4 has latest date.             |
--------------------------------------------------------------------------------------------

如果在这种情况下有更常见或更有效的做法,我愿意重组我的数据库

我一直在使用JSON_ArrayAg(JSON_对象(“id”,item.id,“name”,item.name))来构建JSON对象的数组。如果有更好的/通用的/性能更好的替代方案,我也持开放态度


我已经创建了一个可复制的例子,说明我的情况是可以运行的

架构(MySQL v5.7)


尝试查询#1

SELECT DISTINCT item_location.location_id, locations.city, date, JSON_ARRAYAGG(JSON_OBJECT("id", items.id, "name", items.name)) AS items
FROM item_location 
INNER JOIN items ON item_location.item_id = items.id
INNER JOIN locations ON item_location.location_id = locations.id
GROUP BY items.name, item_location.location_id, date;
select `locations`.`id`, `locations`.`city` as `city`, `itms`.`items` from locations
left join (
SELECT il.location_id AS id, JSON_ARRAYAGG(JSON_OBJECT("name", i.name)) AS items
FROM   item_location il
JOIN   items i ON i.id = il.item_id
GROUP  BY il.location_id
) itms USING (id)  
order by `city`;

预期成果:

| location_id | city         | items                                                    |
| ----------- | ------------ | ———————————————————————————————————————————————————————— |
| 3           | Racine       | [{"id": "1", "name": "1405"}, {"id": "2", "name": "1447"}]  |
| 1           | Kingsville   | [{"id": "3", "name": "1641"}]                              |
| 2           | Wright City  | []                                                       |
这是我最近的查询,但我不确定MySQL是否有办法知道哪个项目是该位置的最新所有者: 查询#1

SELECT DISTINCT item_location.location_id, locations.city, date, JSON_ARRAYAGG(JSON_OBJECT("id", items.id, "name", items.name)) AS items
FROM item_location 
INNER JOIN items ON item_location.item_id = items.id
INNER JOIN locations ON item_location.location_id = locations.id
GROUP BY items.name, item_location.location_id, date;
select `locations`.`id`, `locations`.`city` as `city`, `itms`.`items` from locations
left join (
SELECT il.location_id AS id, JSON_ARRAYAGG(JSON_OBJECT("name", i.name)) AS items
FROM   item_location il
JOIN   items i ON i.id = il.item_id
GROUP  BY il.location_id
) itms USING (id)  
order by `city`;

您可以根据需要将日期添加到上述查询中

你的问题的答案是,以下是需要改进的地方。了解MySQL
EXPLAIN

你需要学习如何使用临时删除;使用filesort等。互联网上有大量教程可供学习

如果你需要进一步的帮助,请告诉我

您可以根据需要将日期添加到上述查询中

你的问题的答案是,以下是需要改进的地方。了解MySQL
EXPLAIN

你需要学习如何使用临时删除;使用filesort等。互联网上有大量教程可供学习


如果您需要进一步的帮助,请告诉我。

考虑处理应用程序中的数据显示问题code@Strawberry那可能是我最后的选择。我可以抓取几个位置,或者使用多个查询并对项目位置的完整列表进行排序,或者使用json解析数组结果并确定哪些项目应该放在哪里。我想利用多个选项来处理业务逻辑或客户端中数据重构的性能问题,并且请参阅在应用程序中考虑数据显示的处理问题。code@Strawberry那可能是我最后的选择。我可以抓取几个位置,或者使用多个查询并对项目位置的完整列表进行排序,或者使用json解析数组结果并确定哪些项目应该放在哪里。如果在业务逻辑或客户端处理数据重组时出现性能问题,我希望利用多个选项。请参阅

| id  | city         | items                                                  |
| --- | ------------ | ------------------------------------------------------ |
| 2   | Wright City | [{"name": "1641"}]                                 |
| 1   | Kingsville   | [{"name": "1641"}]                                     |
| 3   | Racine       | [{"name": "1405"}, {"name": "1447"}, {"name": "1641"}] |
SELECT DISTINCT item_location.location_id, locations.city, JSON_ARRAYAGG(JSON_OBJECT("id", items.id, "name", items.name)) AS items
FROM item_location 
INNER JOIN items ON item_location.item_id = items.id
INNER JOIN locations ON item_location.location_id = locations.id
GROUP BY items.name
EXPLAIN SELECT DISTINCT item_location.location_id, locations.city, JSON_ARRAYAGG(JSON_OBJECT("id", items.id, "name", items.name)) AS items FROM item_location INNER JOIN items ON item_location.item_id = items.id INNER JOIN locations ON item_location.location_id = locations.id GROUP BY items.name