用户表 1 user 用户登录日志表 2 user_login_log
两表通过 member_id 关联
现在 user_login_log 左连接到 user 表中 ( LEFT JOIN )
select * from user left join user_login_log on user.id=user_login_log.member_id
...
问题来了,如何通过联表 如何查询 没有登录过的用户?就是说 查询 user_login_log 表中没有登录日志的用户。
我试过
select * from user left join user_login_log on user.id=user_login_log.member_id where user_login_log.member_id is null 不行
select * from user left join user_login_log on user.id=user_login_log.member_id where user_login_log.member_id="" 也不行
1
FleyX 2019-07-15 18:45:35 +08:00
可以用子查询来解决。类似这样的写法:select * from ( selec * from a left join b on a.id = b.aId )a where a.bId is null
但是:非常不推荐这么写,效率太低了,数据量一大就会慢的怀疑人生。 建议这么来实现这个功能:用户表新增一个字段,记录用户上次登录时间。这样就能方便快捷的进行各种查询。 |
2
zpaopao 2019-07-15 18:54:29 +08:00
SELECT * FROM USER a
WHERE NOT EXISTS (SELECT * FROM user_login_log b on a.id=b.member_id) |
3
zpaopao 2019-07-15 19:02:06 +08:00
我也不知道我的对不对,你可以试试。。。
|
4
JasonTsang OP |
5
lanterboy 2019-07-15 19:12:11 +08:00
2L 正解
|
6
lanterboy 2019-07-15 19:13:47 +08:00
select * from user a
where not exists (select 1 from user_login_log b where a.id=b.member_id) 2L 把 where 打成 on 了 |
7
starsriver 2019-07-15 19:14:34 +08:00 via Android
这么写业务容易出问题
|
8
NullErro 2019-07-15 19:54:17 +08:00
我想知道 left outer join 为啥不行????
user 表结构: +---------+-----------+ | user_id | user_name | +---------+-----------+ | 1 | a | | 2 | b | | 3 | c | +---------+-----------+ login_log 表: +-----------+-------+ | member_id | other | +-----------+-------+ | 2 | te | +-----------+-------+ mysql> select a.user_id, a.user_name -> from -> (select user_id, user_name from tmp_user_0715)a -> left outer join -> (select member_id from tmp_user_login_log_0715)b -> on a.user_id=b.member_id -> where b.member_id is null; +---------+-----------+ | user_id | user_name | +---------+-----------+ | 1 | a | | 3 | c | +---------+-----------+ 2 rows in set (0.01 sec) 完全可以啊 |
9
lolizeppelin 2019-07-15 20:08:57 +08:00
连登陆日志表,用户量大等死吧 233
你以为你是 pg 啊 |
10
ma836323493 2019-07-15 23:00:57 +08:00
|
11
zpaopao 2019-07-16 09:01:31 +08:00
@ma836323493
个人意见:楼主的写法是错误的,在 LEFT JOIN 或者 JOIN 的时候,下面的 WHERE 语句,只是对原始数据表 user_login_log 的进行条件判定,而不是对笛卡尔积,在本身的错误的情况下,且如果 user_login_log 的 MEMBER_ID 是 PRIMARY KEY,是不会出现为空的子集。 |
12
zpaopao 2019-07-16 09:11:28 +08:00
如果楼主不想嵌套,
可以用 FULL OUTER JOIN |
13
LeeSeoung 2019-07-16 09:45:04 +08:00
先把 left join 结果包一层 select,把 is null 的判断放这里试试。我印象中这样写是没问题的。
|
14
husky 2019-07-16 10:04:09 +08:00
一定要联表吗,分两次查?
|
15
fuxiuyin 2019-07-16 10:26:59 +08:00
select user.id, count(user_login_log.id) as count from user left join user_login_log on user.id=user_login_log.member_id group by id having count=0;
|
16
fuxiuyin 2019-07-16 10:27:50 +08:00
实验了一下,没错,这样可以,count user_login_log 表的任意字段就行。
|
17
fuxiuyin 2019-07-16 10:47:22 +08:00
并且这么做应该是比嵌套查询快的。SQL 是描述要什么的语法,字查询更像是程序那种命令式的语法,先做什么后做什么,这样的话数据库自己是没什么优化的余地的。
回复不支持 md,所以要好好看的话还是复制走吧,join 会用 index,字查询就是扫表。 https://paste.ubuntu.com/p/MsFyKXbrW3/ |
18
zpaopao 2019-07-16 12:55:47 +08:00
感觉自己说复杂了,不知道为什么发不出来,其实楼主用 LEFT JOIN 也可以,只是不能写 where member_id is null 应该写 where 登陆日期 is null .. (至少我在自己本地数据库创建了 2 个表试了下是没问题的)
|
19
zpaopao 2019-07-16 13:01:52 +08:00
初学 SQL 的我,感觉自己也混乱了。。。楼主都试试吧···
|
20
fuxiuyin 2019-08-04 18:12:11 +08:00
今天看自己的回复列表的时候突然看到这个,反应过来了,这个就是集合 A-集合 B
select * from user left join user_login_log on user.id=user_login_log.member_id where user_login_log.member_id is null; 应该是可以的,然后又试了一下,这个在 PostgreSQL 上是没问题的,MySQL 上有问题,是 MySQL 自己的问题,MySQL 的实现看上去不是完整的关系运算。 https://stackoverflow.com/questions/406294/left-join-vs-left-outer-join-in-sql-server 可以看一下第一个回答的图。 |