thinphp+mysql 實現 分表(不同表)日誌,group by,order by 查詢
阿新 • • 發佈:2020-12-11
主題列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, greenwillow
貢獻主題:https://github.com/xitu/juejin-markdown-themes
theme: juejin
highlight:
表結構
這幾張表都結構都是相同的,除了儲存的資料不同
要實現什麼呢?
每個表的uuid進行分組,並且以id最新的排序
根據日期範圍,實現批量查詢不同月份的表
程式碼
controller
<?php /** * Created by. * User: Jim * Date: 2020/11/17 * Time: 14:41 */ namespace app\admin\controller\analysis; use app\admin\controller\master\Common; use app\admin\model\master\Analysis; use think\Db; use think\facade\Config; /** * 前端使用者每個頁面 瀏覽的資訊 * Class Tracker * @package app\admin\controller */ class Tracker extends Common { static $tablePrefix; public function initialize() { parent::initialize(); // TODO: Change the autogenerated stub self::$tablePrefix = Config::get('database.analysis.prefix'); $this->model = new \app\admin\model\analysis\Tracker(); $tablesName = $this->getBetweenTable('2020-11',date('Y-m')); $this->assign(compact('tablesName')); } public function index() { return $this->fetch(); } /** * 資訊列表 */ public function list() { $subQuery = $this->model ->name($this->model->getTableName()) ->where($this->model->search()) ->order('id desc') ->buildSql(); $lists = $this->model ->table($subQuery . 'a') ->field('*,count(*) survival_time') ->order('id desc') ->group('uuid') ->paginate($this->limit); _lists($lists); } /** * 資料匯出 */ public function export() { $time = $this->request->get('time'); $time = json_decode($time, true)['create_time']; // 沒有選擇時間,預設為本月的 if ($time == '') { $subQuery = $this->model ->order('id desc') ->buildSql(); $datas = $this->model ->table($subQuery . 'a') ->field('*,count(*) survival_time') ->order('id desc') ->group('uuid') ->select(); } else { //根據日期查詢 多個表 [$start_time, $last_time] = explode(' ~ ', $time); $tablesName = $this->getBetweenTable($start_time, $last_time); /** * 查詢指定的時間 */ $datas = []; foreach ($tablesName as $table){ $subQuery = $this->model ->name($table) ->whereTime('create_time', 'between', [$start_time, $last_time]) ->order('id desc') ->buildSql() ; $data = $this->model ->table($subQuery . 'a') ->field('*,count(*) survival_time') ->order('id desc') ->group('uuid') ->select() ->toArray(); $datas = array_merge($datas,$data); } } $lists = []; foreach ($datas as $row) { $item['product_name'] = $row['product_name']; $item['product_code'] = $row['product_code']; $item['user_formal'] = $row['user_formal']; $item['ip_formal'] = $row['ip_formal']; $item['keep_time'] = $row['keep_time']; $item['survival_time'] = "約{$row['survival_time']}秒"; $item['create_time'] = $row['create_time']; $item['url'] = $row['url']; $item['referer'] = $row['referer']; $item['user_agent'] = $row['user_agent']; $lists[] = $item; } $name = '使用者行為分析列表—' . date('Y-m-d His', time()); $headers = [ '產品名稱', '產品程式碼', '郵箱', 'IP', '留存時間', '頁面活動時間', '訪問時間', 'URL', '來源URL', '訪問方式', ]; exportDataCsv($lists, $headers, $name); } /** * 獲取時間段內的存在的表 列表 * @param $start_time * @param $last_time * @return array */ private function getBetweenTable($start_time, $last_time) { $time1 = strtotime($start_time); // 自動為00:00:00 時分秒 兩個時間之間的年和月份 $time2 = strtotime($last_time); $monarr[] = date('Ym', $time1);; while (($time1 = strtotime('+1 month', $time1)) <= $time2) { $monarr[] = date('Ym', $time1); // 取得遞增月; } $names = []; foreach ($monarr as $row) { $tableName = 'tracker_' . $row; $check = Db::connect('analysis')->query("show tables like '" . self::$tablePrefix .$tableName . "'"); if (!$check) continue; $names[] = $tableName; } return array_reverse($names); } }
model
<?php /** * Created by. * User: Jim * Date: 2020/10/30 * Time: 9:09 */ namespace app\admin\model\analysis; use app\admin\model\master\Analysis; use think\Db; use think\facade\Request; use function Complex\theta; class Tracker extends Analysis { protected function initialize() { parent::initialize(); // TODO: Change the autogenerated stub $this->name = 'tracker_' . date('Ym'); } protected $append = [ 'ip_formal', 'user_formal', 'keep_time', ]; public function getKeepTimeAttr($value, $data) { try { [$start_time, $uuid] = explode('|', $data['uuid']); $last_time = $data['create_time']; $result = ($last_time + 2) - $start_time; return gmdate('H:i:s', $result); } catch (\Exception $e) { return ''; } } public function getIpFormalAttr($value, $data) { $value = $value ?? $data['ip'] ?? ''; if (!$value) return ''; return long2ip($value); } public function getUserFormalAttr($value, $data) { $value = $value ?? $data['user_id'] ?? ''; if (!$value) return ''; return Db::name('member')->where(['id' => $value])->cache(true)->value('email'); } /** * 搜尋 * @return array */ public function search() { $params = Request::get(); if (!isset($params['searchParams'])) return []; $searchParams = json_decode($params['searchParams'], true); $where = []; unset($searchParams['create_time']); foreach ($searchParams as $field => $value) { $value = trim($value); if ($field == 'tableName') continue; if ($value == '') continue; $where[] = [$field, 'like', "%{$value}%"]; } return $where; } /** * 搜尋 * @return array */ public function getTableName() { $params = Request::get(); if (!isset($params['searchParams'])) return $this->name; $searchParams = json_decode($params['searchParams'], true); $tableName = $searchParams['tableName'] ?? $this->name; return $tableName; } }
使用、
(base64)根據日期查詢所有資料
http://www.au.test.cc/analysis/tracker/export?time={%22create_time%22:%222020-11-11%20~%202020-12-25%22,%22tableName%22:%22tracker_202011%22,%22product_name|product_code%22:%22%22
(base64)選擇指定的表以及搜尋關鍵字
http://www.au.test.cc/analysis/tracker/list?page=1&limit=15&searchParams=%7B%22create_time%22%3A%222020-11-11%20~%202020-12-25%22%2C%22tableName%22%3A%22tracker_202011%22%2C%22product_name%7Cproduct_code%22%3A%22123%22%7D
http://www.au.test.cc/analysis/tracker/list?page=1&limit=15
{
"code":0,
"msg":"",
"count":5,
"data":[
{
"id":62,
"user_id":4403,
"uuid":"1605661840|d87c7ca6-0ced-4c62-b59f-e03669848652",
"ip":2130706433,
"url":"http://www.index.test.cc/goods/detail/id/1394.html",
"product_name":"KN95 Face Mask",
"product_code":"PCA024",
"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36",
"referer":"http://www.index.test.cc/",
"create_time":"2020-11-18 11:17:50",
"survival_time":25,
"ip_formal":"127.0.0.1",
"keep_time":"02:07:12"
},
{
"id":61,
"user_id":4403,
"uuid":"1605669370|649bb0b5-336e-43e9-9433-57e4974c0bab",
"ip":2130706433,
"url":"http://www.index.test.cc/goods/detail/id/1395.html",
"product_name":"30ml Hand Sanitiser Gel",
"product_code":"PCA04",
"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36",
"referer":"http://www.index.test.cc/goods/detail/id/1394.html",
"create_time":"2020-11-18 11:17:50",
"survival_time":21,
"ip_formal":"127.0.0.1",
"keep_time":"00:01:42"
}
]
}