我有两张桌子:
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及其信号强度范围内的接入点。
无论如何,我有一个方法,我提供最多4个MAC地址的List
,我需要查找包含这4个地址的所有locations
。
现在我以编程方式执行此操作:
1.取X,Y
及其mac地址的最高信号强度
2. SELECT * FROM signals WHERE mac = ScanResult.BSSID
3.从返回的signals.location_id
中创建ID数组
4.批量选择所有位置,如果它们的ID在阵列中,以及与这些位置相关的所有信号
5.复杂循环循环创建一个数组,其中包含我在List
中提供的所有4个mac地址的所有位置,并删除其他地址。
这非常混乱,并且有冗余查询,但由于我对SQL不是很好,所以它是一个有效的补丁。
现在我想知道我是否可以单独使用SQL并返回包含这4个mac地址的locations
。
我有:
SELECT locations.*, signals.* FROM locations INNER JOIN signals ON locations.id = signals.location_id;
如果我只需排除关系为1:1的位置,那么我就不那么困惑了,但这里每个位置最多有4个信号。有没有办法提供一个"阵列"查询并从JOIN
说出删除所有不包含此数量的mac地址和这些mac地址的locations
。
答案 0 :(得分: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
答案 1 :(得分:2)
有没有办法可以提供一个"阵列"查询
是的,这有一个operator。您甚至可以提供另一个查询作为参数
SELECT * FROM locations WHERE id IN (SELECT location_id FROM signals WHERE mac = ScanResult.level);
NOT IN
排除列表中包含的元素答案 2 :(得分: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;