2015-06-03 5 views
1

У меня есть две таблицы:MySQL исключающие результаты РЕГИСТРИРУЙТЕСЬ

locations 
--------------------- 
| id INT, PK, AI | 
| x  INT   | 
| y  INT   | 
--------------------- 

signals 
--------------------- 
| id INT, PK, AI | 
| location_id INT | 
| mac   INT | 
| strength INT | 
--------------------- 

Одно место может (будет) иметь до максимум 4 сигналов. Где местоположение X, Y указывает на изображение, а сигнал - Точка доступа в диапазоне X, Y и уровень сигнала.

Во всяком случае у меня есть способ, которым я предоставляю List до 4 MAC-адресов, и мне нужно найти все locations, которые содержат эти 4 адреса.

Прямо сейчас я делаю это программно:
1. Возьмите верхний уровень сигнала на X,Y и это макинтош адреса
2. SELECT * FROM signals WHERE mac = ScanResult.BSSID
3. Создать массив идентификаторов из возвращаемой signals.location_id
4. Навалом выберите все местоположения, если их идентификатор находится в массиве вместе со всеми сигналами, относящимися к этим местоположениям.
5. Сложный цикл в цикле создает массив, содержащий все местоположения, которые имеют в своем отношении все 4 адреса mac, которые я предоставил в, и удалять другие.

Это невероятно грязно и имеет избыточные запросы, но поскольку я не очень хорошо разбираюсь в SQL, это был патч, который работал.

Теперь мне было интересно, могу ли я сделать это с помощью только SQL и вернуть locations, которые содержат эти 4 адреса mac.

у меня есть:

SELECT locations.*, signals.* FROM locations INNER JOIN signals ON locations.id = signals.location_id; 

я был бы менее смущен, если бы я только должен был исключить места, где соотношение будет 1: 1, но здесь каждый имеет места до 4-х сигналов. Есть ли способ, которым я мог бы предоставить «массив» для запроса и сказать, что JOIN удалите все locations, которые не содержат это количество адресов mac и этих адресов.

ответ

1

Решение Andomar корректно на основе запроса образца. Однако структура данных отличается от запроса, и запрос на самом деле не имеет смысла. Я думаю, что это все, что необходимо:

SELECT s.location_id 
FROM signals s 
WHERE s.MAC in (1, 2, 3, 4) 
GROUP BY s.location_id 
HAVING COUNT(DISTINCT s.MAC) = 4; 
2

Есть ли способ, которым я мог бы обеспечить «массив» на запрос

Да, есть operator для этого. Вы даже можете предоставить другой запрос в качестве параметра

SELECT * FROM locations WHERE id IN (SELECT location_id FROM signals WHERE mac = ScanResult.level); 
  • вы также можете использовать NOT IN, чтобы исключить элементы, которые содержатся в списке
+0

Это вернет любое местоположение, имеющее любой из MAC-адресов. OP хочет местоположения, у которых есть ВСЕ предоставленные MAC-адреса. – Andomar

3

Вы можете использовать пункт having, чтобы обеспечить местоположение имеет все четыре MAC-адреса:

SELECT l.id 
,  l.x 
,  l.y 
FROM locations l 
JOIN signals s 
ON  s.location_id = l.location_id 
WHERE s.MAC in (1, 2, 3, 4) 
GROUP BY 
     l.id 
,  l.x 
,  l.y 
HAVING COUNT(DISTINCT s.MAC) = 4 
Смежные вопросы