MySQL Оператор select с несколькими объединениями возвращает дублированные записи - PullRequest
0 голосов
/ 12 января 2020

У меня есть 4 таблицы со следующей структурой:

Table Groups
  Groupid
  groupname
  groupadmin

Table GroupMembership
  devid
  groupid

Table GroupLocator
  devid
  name
  pass
  color
  sampling
  connected
  forget
  trace

Table GroupTracker
  devid
  groupid
  latitude
  longitude
  timestamp

Существует только один groupid = '1' с groupname = "FBorges"
Таблица GroupLocator имеет 2 записи где devid указывает на grouid = '1' в GroupMembership
GroupTracker имеет две записи, где groupid = '1'

Когда я запускаю следующий SELECT:

SELECT GroupLocator.name, GroupLocator.color, GroupLocator.sampling,
       GroupLocator.forget, GroupLocator.connected, GroupLocator.trace,  
       Groups.groupname, GroupTracker.latitude, GroupTracker.longitude, 
       GroupTracker.timestamp  
FROM GroupMembership 
JOIN GroupLocator    ON GroupLocator.devid=GroupMembership.devid
JOIN Groups          ON Groups.groupid=GroupMembership.groupid 
JOIN GroupTracker    ON GroupTracker.groupid=GroupMembership.groupid 
WHERE GroupMembership.groupid=1;

I получить результат:

name     color sampling forget connected trace groupname  latitude  longitude  timestamp  
PCBorges 2     1        45     0         1     FBorges  -22.883639 -42.822542  2020-01-08 20:29:24
Test     3     2        45     1         0     FBorges  -22.883639 -42.822542  2020-01-08 20:29:24
PCBorges 2     1        45     0         1     FBorges  -22.873639 -42.322542  2020-01-11 16:56:30
Test     3     2        45     1         0     FBorges  -22.873639 -42.322542  2020-01-11 16:56:30

Я надеюсь получить:

name     color sampling forget connected trace groupname  latitude  longitude  timestamp 
PCBorges 2     1        45     0         1     FBorges  -22.883639 -42.822542  2020-01-08 20:29:24
Test     3     2        45     1         0     FBorges  -22.883639 -42.822542  2020-01-08 20:29:24

1 Ответ

1 голос
/ 12 января 2020

РЕДАКТИРОВАТЬ: удалил мои предыдущие предположения после того, как структура и данные были предоставлены и написал новый ответ :

Я считаю, что вы хотите присоединиться к GroupTracker на devid, а не на groupid. Groupid 1 соответствует обеим строкам таблицы GroupTracker, поэтому он предоставит два результата для каждой 1 строки в GroupMemebership. Devid соответствует только одному ряду. Правильный JOIN более эффективен, чем ваше текущее решение GROUP BY (в комментариях), и может также давать более согласованные результаты по мере роста вашей базы данных.

SELECT gl.name, gl.color, gl.sampling,
   gl.forget, gl.connected, gl.trace,  
   g.groupname, gt.latitude, gt.longitude, 
   gt.timestamp  
FROM GroupMembership AS gm
JOIN GroupLocator AS gl    ON gm.devid = gl.devid
JOIN Groups AS g           ON gm.groupid = g.groupid 
JOIN GroupTracker AS gt    ON gm.devid = gt.devid 
WHERE gm.groupid=1
;

Я присвоил псевдонимы всем вашим таблицам, так что запрос намного короче и, следовательно, быстрее писать. Я также поменял местами все ваши предложения JOIN. Я предпочитаю иметь левый стол слева и правый стол справа. Облегчает чтение. Эти два изменения не важны. Это всего лишь стиль. Запрос будет отлично работать без них.

...