0

我有一个工人表和一个相关的 workerGeofence 表。

CREATE TABLE IF NOT EXISTS `workergeofences` (
`ID` int(11) NOT NULL,
  `WorkerID` varchar(20) NOT NULL,
  `GeofenceID` int(11) NOT NULL,
  `isActive` tinyint(4) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=107 DEFAULT CHARSET=latin1;

我只需要返回 workerGeofences 表中至少有一个 isActive 为 1 的条目的工人。

我可以通过以下方式获得预期的结果:

    SELECT distinct w.ID, Title, FName, SName, Email, Birthday, Address, Phone, description,
 companyID 
FROM Workers w WHERE companyID = ? 
and w.ID IN (SELECT WorkerID FROM WorkerGeofences WHERE isActive <> 0)
    limit ?,10

但是 in 子查询是详尽的,因为当我运行解释时,我可以看到它正在扫描整个表。我将如何解决这个问题?

4

3 回答 3

2

你在正确的轨道上,但你不应该需要select distinct. 这会减慢查询速度,除非您知道有重复项——这不太可能,因为您选择的是WOrkers.Id.

SELECT w.* 
FROM Workers w 
WHERE w.companyID = ? AND
      EXISTS (SELECT 1
              FROM workerGeofences wg
              WHERE w.ID = wg.WorkerID AND wg.isActive <> 0
             )
LIMIT ?, 10;

然后,对于此查询,您需要索引Workers(CompanyId, Id)workerGeofences(WorkerId, isActive)

select *注意:我只是为了方便而放入。我假设所有的列都来自Workers表。

于 2016-02-03T14:37:39.810 回答
1

首先,你的加入是错误的!您没有比较两个表上的任何公共列,您应该像这样添加 where workerGeofences.workerID = w.id :

SELECT  w.ID, Title, FName, SName, Email, Birthday, Address, Phone,
        description, companyID
    FROM  Workers w
    join  workerGeofences
    WHERE  workerGeofences.workerID = w.ID companyID = ?
      and  w.ID IN (
        SELECT  WorkerID
            FROM  WorkerGeofences s
            WHERE  isActive <> 0
              and  s.workerID = w.id
                   )
    limit  0,10 

其次,您没有从第二个表中选择任何内容,因此连接是不必要的,并且在您的 IN 语句中,您没有比较正确的 ID,因此您的查询应该是:

SELECT  w.ID, Title, FName, SName, Email, Birthday, Address, Phone,
        description, companyID
    FROM  Workers w
    WHERE  companyID = ?
      and  w.ID IN (
        SELECT  WorkerID
            FROM  WorkerGeofences s
            WHERE  isActive <> 0
              and  s.workerID = w.ID
                   )
    limit  0,10 

此外,您可以使用 EXISTS() 。

SELECT  w.ID, Title, FName, SName, Email, Birthday, Address, Phone,
        description, companyID
    FROM  Workers w
    WHERE  companyID = ?
      and  exists 
      ( SELECT  1
            FROM  WorkerGeofences s
            WHERE  isActive = 1
              and  s.workerID = w.ID
      )
    limit  0,10
于 2016-02-03T14:30:00.883 回答
1

为了使用 JOIN 的完整性:

SELECT DISTINCT w.ID,
       w.Title, 
       w.FName, 
       w.SName, 
       w.Email, 
       w.Birthday, 
       w.Address, 
       w.Phone, 
       w.description, 
       w.companyID
  FROM Workers w 
  JOIN WorkerGeofences wg
    ON wg.workerID = w.id
   AND wg.isActive = 1
 WHERE w.companyID = ? 
 LIMIT ?,10
于 2016-02-03T14:40:01.583 回答