如何选择给定参数始终为true的所有用户

时间:2012-01-14 02:18:17

标签: mysql sql

我有一个表格,其中包含用户和他们被看到的位置:

user_id  | latitude | longitude | date_seen
-------------------------------------------
1035     | NULL     | NULL      | April 25 2010
1035     | 127      | 35        | April 28 2010
1038     | 127      | 35        | April 30 2010
1037     | NULL     | NULL      | May 1 2010
1038     | 126      | 34        | May 21 2010
1037     | NULL     | NULL      | May 24 2010

日期是数据库中的常规时间戳;我在这里简化了它们。

我需要获取纬度和经度始终为null的用户列表。因此在上面的示例中,用户1037-用户1035具有一行具有lat / lon信息,1038具有两行具有lat / lon信息,而对于用户1037,在两行中信息都为空。

我可以用什么查询来实现这个结果?

4 个答案:

答案 0 :(得分:3)

select distinct user_id
from table_name t
where not exists(
    select 1 from table_name t1 
    where t.user_id = t1.user_id and 
    t1.latitude is not null and
    t1.longitude is not null
)

您可以阅读此查询:告诉我所有未在表格的任何行中设置纬度和长度不同于null的用户。在我看来exists在这种情况下是首选(不存在),因为即使使用表扫描(不是查找行的最佳方式),它在找到特定行之后就会停止(不需要{{1}所有行)。

详细了解此主题:Exists Vs. Count(*) - The battle never ends...

答案 1 :(得分:1)

试试这个,它应该有效。

    SELECT user_id, count(latitude), count(longitude) 
    FROM user_loc 
    GROUP BY user_id HAVING count(latitude)=0 AND count(longitude)=0;

在MySQL中测试。

答案 2 :(得分:0)

尝试:

SELECT * FROM user WHERE latitude IS NULL AND longitude IS NULL;

- 编辑 -

第二次尝试(未经测试,但是我之前使用过的查询构建了它):

SELECT user_id, CASE WHEN MIN(latitude) IS NULL AND MAX(latitude) IS NULL THEN 1 ELSE 0 END AS noLatLong FROM user GROUP BY user_id HAVING noLatLong = 1;

答案 3 :(得分:0)

这有效:

SELECT  DISTINCT user_id
FROM    table
WHERE   latitude  IS NULL
    AND longitude IS NULL
    AND NOT user_id IN
        (SELECT  DISTINCT user_id
         FROM    table
         WHERE   NOT latitude  IS NULL
             AND NOT longitude IS NULL)

结果:

1037

(这里用SQLite验证语法)

但是:即使不在这里使用COUNT,我的陈述也必须扫描所有表格行,因此MichałPowaga的陈述更有效率。

原理:

  • 获取带有lat / lon记录的user_ids列表以进行比较(您希望从最终结果中排除这些记录) - 优化:在这里使用EXISTS ...
  • 获取没有lat / lon记录(您感兴趣的)的user_ids列表
  • 减少第一个列表中存在的所有ID - 优化:在这里使用EXISTS ......
  • make user_ids DISTINCT,因为该示例显示了每个user_id的多个条目(但您只想要唯一的ID)