mysql - 使用mysql选择随机记录
问题描述
我的 MySql 数据库中有两个表:
员工表:
id | name | projectcount
---------------------------------
5 | john | 1
7 | mike | 1
8 | jane | 0
项目表:
id | name | employeeId
---------------------------------
1 | pro1 | 5
2 | pro2 | 7
3 | pro3 | 8
CREATE TABLE EmployeeTable (
id INT,
name VARCHAR(30),
projectcount int
);
CREATE TABLE ProjectTable (
id INT,
name VARCHAR(30),
employeeId INT
);
INSERT INTO EmployeeTable (id, name, projectcount) VALUES
(5, "john", 1),
(7, "mike", 1),
(8, "jane", 0);
INSERT INTO ProjectTable (id, name, employeeId) VALUES
(1, "pro1", 5),
(2, "pro2", 7),
(3, "pro3", 8);
我想从项目表中选择 3 个随机记录并更新员工表中的项目计数并使用选择查询返回这些记录。
我使用存储过程的方法:
DECLARE userId1 int DEFAULT 0;
DECLARE userId2 int DEFAULT 0;
DECLARE userId3 int DEFAULT 0;
DECLARE projectId1 int DEFAULT 0;
DECLARE projectId2 int DEFAULT 0;
DECLARE projectId3 int DEFAULT 0;
select id, employeeid into projectId1, userId1 from project order by RAND() LIMIT 1;
select id, employeeid into projectId2, userId2 from project order by RAND() LIMIT 1;
select id, employeeid into projectId3, userId3 from project order by RAND() LIMIT 1;
update employee set projectcount = projectcount + 1 where id = userId1;
update employee set projectcount = projectcount + 1 where id = userId2;
update employee set projectcount = projectcount + 1 where id = userId3;
select * from project where id in (projectId1, projectId2, projectId3);
上面的代码有效,但以更静态的方式编写。是否对此进行了任何改进以看起来更清洁。谢谢。
解决方案
计划A
“是否对此进行了任何改进以看起来更清洁。” 一次只做一个请求。
由于这可能不满足您对“更清洁”的预期含义,我将继续:
B计划
翻转东西。并使用事务。
它的运行速度提高了 3 倍,并修复了一个潜在的错误。这算不算“清洁工”?
BEGIN;
SELECT @ids := GROUP_CONCAT(id)
-- I assume that `id` is the PRIMARY KEY of `project`?
from project
order by RAND() LIMIT 3;
-- That will run 3 times as fast as 3 separate SELECTs.
-- It avoids tallying the same id 3 times
-- but it may hit the same employee 3 times
SET @sql = CONCAT("UPDATE employee
SET projectcount = projectcount + 1
WHERE id IN (", @ids, ")");
PREPARE _sql FROM @sql;
EXECUTE _sql;
DEALLOCATE PREPARE _sql;
... -- similar execute to get the `SELECT *`
COMMIT;
如果您有数百万行要从中挑选,那么请注意,这ORDER BY RAND()
始终需要全表扫描和排序。这里有一些加快速度的方法:http: //mysql.rjweb.org/doc.php/random
C计划
收紧规范(没有重复项目,双重分配用户,定义“更清洁”等)然后我们可以寻找其他方法。
推荐阅读
- firebase - 在 Firebase 中,只有当事件具有特定参数时,我才能触发转换?
- sql - 如果查询返回 0 行,则应用默认过滤器 - Oracle Plsql
- c# - Xamarin.Forms 从 api 端点接收图像
- laravel - 如何使用 Laravel Guzzle HTTP 客户端上传文件
- html - 如何在 flex-column 中的元素之间添加空格?
- javascript - onClick 从组件中删除数据
- linux - 有什么方法可以强制程序/软件在 Linux 中使用系统代理?
- tcp - 如何防止 Windows10 向特定 IP 和 PORT 发送 TCP RST?
- python - 难以理解 python 用户定义的函数
- javascript - 如何在Angular的组件/服务中执行任何功能之前先加载http数据?