每次记录SQL的点滴
项目中遇到SQL, 尤其是跟分组有关, 或者count, sum相关, 写的不是很好.有时间就记录点吧, 没时间就算了..
例如有一个关于统计的需求,要求主表不管有无从表的统计数据,都要显示出来:
数据
用户名称 | 访问记录 | 访问时间 |
---|---|---|
用户1 | 访问url | 5-18 |
用户2 | 访问url | 3-18 |
用户1 | 访问url | 5-16 |
用户3 | NULL | NULL |
用户列
来自主表, 其他两列
均来自从表, 两者之间通过用户id
进行关联
想要得到的数据(在5月份这个时间段的访问次数):
用户名称 | 访问次数 |
---|---|
用户1 | 2 |
用户2 | 0 |
用户3 | 0 |
写完的SQL结构
SELECT 用户名, count(统计某字段) 访问次数 FROM (
-- 子查询1(查询某些条件的用户表)
-- 当然实际业务要复杂的多, 可能是多表关联出来的结果集
) t1
-- t1 相当于一张表, 不管里面的查询关联了多少表
LEFT JOIN (
-- 子查询2(查询某些条件的另一张表)
WHERE time = 5月份
) t2 ON t1.id = t2.id
-- t2 是从表, 数据的主要来源记录
GROUP BY t1.id
我遇到的问题
- 如果LEFT JOIN t2 , 不通过子查询会怎么样?
SELECT 用户名, count(统计某字段) 访问次数 FROM (
-- 子查询1(查询某些条件的用户表)
) t1
LEFT JOIN t2表名 ON t1.id = t2.id
WHERE time = 5月份
GROUP BY t1.id
最开始我是这样写的, 但是出现的数据会变成这样:
用户名称 | 访问次数 |
---|---|
用户1 | 2 |
发现用户2, 用户3 不见了….
原因: 关联表时 , 没有用子查询, 那么关联的所有访问记录的数据, 但是如果现在需要查某个时间段的数据, 再最后面肯定会用WHERE time = 5月份
这样的语句, 导致用户2, 因为它存在访问记录, 但是时间在3月份, 这样它会直接被筛掉, 包括用户3, 它甚至不存在访问记录, 更会被筛掉.