最近完成了一項目,其中有一個抽檢的需求,大體描述一下至關於這麼一個案例:php
每位用戶提交了數量不等的數據條目信息存儲在一張mysql表內,如何實現按百分比抽取每位用戶的提交信息?mysql
實例化下這個需求:100個用戶每人各自提交了數量不等的數據累加起來共1000條存放在一張表內,你如何抽取每位用戶提交數量的10%來抽查?sql
若是用代碼將這1000條數據全讀出來,而後按用戶分組統計數量計算百分比在整合出最終數據,那可很是耽誤時間。code
咱們要的最終結果,其實能夠用一條sql語句就能夠完成了。table
思路:經過不一樣sql語句的查詢結果構造兩張表,一張表(table_b)按用戶分組,組內數據隨機排列,並加上序號; 一張表(table_c)存儲每一個用戶應該抽取的數據條數。而後根據這兩張表就能夠……class
咱們從一張表(tasklist)出發:sql語句
status =0 表示未選中的狀態。統計
第一步,構建表table_b數據
咱們將用戶分組,組內順序隨機排列。項目
SELECT `id`,`uname`,`taskinfo` FROM `tasklist` ORDER BY `uname` ASC, RAND();
執行sql語句,咱們能夠獲得這樣的查詢結果
將查詢結果視做一張表
$table_b = '(SELECT `id`,`uname` FROM `user_work_info` ORDER BY `uname` ASC,RAND())';
給組內加上編號,sql語句變成
SELECT `a`.`id` AS `id`,`a`.`uname` AS `uname`,@row:=IF(@u=`uname`,@row+1,1) AS `no`, @u:=`uname` FROM $table_b AS `a`,(SELECT @row:=0,@u:=0) AS `b`
執行,能夠獲得這樣的查詢結果
將查詢結果當成一張表
$table_b = '(SELECT `a`.`id` AS `id`,`a`.`uname` AS `uname`,@row:=IF(@u=`uname`,@row+1,1) AS `no`, @u:=`uname` FROM ' . $table_b . ' AS `a`,(SELECT @row:=0,@u:=0) AS `b`) ';
如今咱們構建的表table_b完畢;
第二步,咱們來構建表table_c,這張表將存儲了每一個用戶會被抽取數據的條數。
①執行sql語句
SELECT `uname`,COUNT(`id`) AS `total` FROM `tasklist` GROUP BY `uname`
能夠獲得每一個用戶提交的數據條數,total爲用戶提交的數據條數。
②假設每組抽取的百分比爲50% , 那麼sql語句只要作這樣的修改就能夠了
SELECT `uname`,CEIL(COUNT(`id`) * 50/100) AS `top` FROM `tasklist` GROUP BY `uname`;
執行能夠獲得
③將查詢結果視做一張表,咱們就獲得了表table_c
$table_c = '(SELECT `uname`,CEIL(COUNT(`id`) * 50/100) AS `top` FROM `tasklist` GROUP BY `uname`) ';
第三步,若是咱們執行這樣的sql語句,
SELECT `b`.`id` AS `id`,`b`.`uname` AS `uname`,`b`.`no`,`c`.`top` AS `top` FROM $table_b AS `b`,$table_c AS `c` WHERE `b`.`uname`=`c`.`uname`;
能夠獲得
看到這個查詢結果,你們應該都知道咱們怎麼用一條sql語句來實現從一張mysql表裏來按比例隨機抽取每一個用戶提交的數據信息了。
$table_b = '(SELECT `id`,`uname` FROM `tasklist` ORDER BY `uname` ASC,RAND())'; $table_b = '(SELECT `a`.`id` AS `id`,`a`.`uname` AS `uname`,@row:=IF(@u=`uname`,@row+1,1) AS `no`, @u:=`uname` FROM ' . $table_b . ' AS `a`,(SELECT @row:=0,@u:=0) AS `b`) '; $table_c = '(SELECT `uname`,CEIL(COUNT(`id`) * 50/100) AS `top` FROM `tasklist` GROUP BY `uname`) '; $sql = 'UPDATE `tasklist` AS `a`,' . $table_b . ' AS `b`,' . $table_c . ' AS `c` SET `a`.`status`=1 WHERE `a`.`id`=`b`.`id` AND `b`.`uname`=`c`.`uname` AND `b`.`no`<`c`.`top`';
設置status=1, 表示該條記錄被選中。