掌握SQL LIMIT子句:控制查询中的行数

上周看那个SQL教程。

LIMIT子句挺好用的。

就是限制返回行数。

比如这样。

SELECT id, name FROM users LIMIT 1 0;
就只返回1 0行。

分页用得很多。

比如第二页。

SELECT FROM products LIMIT 1 0 OFFSET 1 0;
就跳过前1 0行。

再选1 0行。

测试数据也方便。

不用全表扫描。

ORDER BY得跟上。

不然顺序乱。

OFFSET太大慢。

比如跳一百万行。

肯定不行。

不同数据库不一样。

MySQL用LIMIT。

SQL Server用TOP。

Oracle用ROWNUM。

SQLite也支持。

总之挺好。

你看着办。

无意中测试了下MySQL里面的join操作,发现还是存在理解偏差

上周有个客人问我,为什么MySQL的JOIN操作结果和预期的不一样,特别是行数不对,还影响到数据统计和性能。
我给他分析了一下。

首先,我们看个具体的例子。
他创建了两个表test1 和test2 ,每个表都有id字段,各四行记录,id分别是1 、2 、2 、3 然后他执行了一个JOIN查询,select from test1 m, test2 n where m.id = n.id and n.id = 2 ;结果出来是四行,其中两行是重复的。
他预期的是两行,因为test1 里id=2 的有两行。

问题出在哪里呢?JOIN操作的本质是返回两个表中满足条件的所有记录组合,不是只返回驱动表的记录。
所以即使test1 里id=2 的只有两行,JOIN后也是四行,因为test2 里也有id=2 的记录。

那怎么办呢?他可以试试使用DISTINCT或者GROUP BY,但这样会把重复的行去掉了,不符合他的需求。
更好的办法是使用半连接,比如用IN或EXISTS子查询,这样只返回驱动表中满足条件的记录。
比如他可以这样写:select m.id from test1 m where m.id in (select n.id from test2 n where m.id = n.id and n.id = 2 );这样就能得到他预期的两行记录。

不过,JOIN操作也有副作用,比如会导致数据统计偏差和性能问题。
比如COUNT()会返回组合后的总行数,而不是驱动表的匹配行数。
如果表里有很多重复数据,过滤这些数据会很消耗资源,尤其是在分布式环境中。

所以,我的建议是,明确你的查询需求,选择合适的查询方式,比如半连接。
尽量减少不必要的JOIN操作,尤其是在只需要驱动表数据的时候。
在分布式环境中,JOIN操作可能会带来性能问题,所以要特别注意。

反正你看着办,JOIN操作虽然强大,但用不好确实会出问题。
理解它的本质,选择合适的查询方式,才能更好地满足业务需求,优化数据库性能。
我还在想这个问题,以后可能还会给你更多建议。

sql中count的用法

记得有一次,我在一家小型公司做数据库管理员,那时候公司里有个销售部门,老板想了解这个月销售部门一共卖出了多少产品。
我打开数据库,看到销售表里有一个“数量”字段,就随手写了个SQL语句:
SELECT COUNT() FROM sales WHERE department = 'Sales';
结果一出来,是3 0,老板挺高兴,说这个月的销售情况不错。
后来我又好奇地想,要是只统计有销售记录的员工数量呢?我就稍微修改了一下语句:
SELECT COUNT(sales_id) FROM sales WHERE department = 'Sales';
这个月有销售记录的员工是2 8 个,少了两个,原来是两个销售员请假了。
这个小小的经历让我意识到,COUNT函数虽然简单,但用得好,能解决实际问题。
等等,还有个事,我突然想到,如果我要统计一下公司里有多少不同城市的客户,那我得用DISTINCT关键字。
不过,得注意,DISTINCT是不统计NULL值的。