業務常將日誌按天分表 (如 tbl_req_YYYYMMDD),查詢跨月資料需合併多張表結果。利用儲存過程動態產生 UNION SQL,避免手工拼接。
DROP PROCEDURE IF EXISTS unionSp;
DELIMITER //
CREATE PROCEDURE unionSp(
IN sTime VARCHAR(32), -- 起始日期 格式 YYYYMMDD
IN eTime VARCHAR(32), -- 結束日期 格式 YYYYMMDD
IN tchema VARCHAR(32) -- 目標資料庫
)
BEGIN
DECLARE sqlVar VARCHAR(1024000) DEFAULT '';
DECLARE rest INT DEFAULT 100;
DECLARE tableName VARCHAR(1024);
DECLARE cnt INT;
WHILE rest > 0 DO
SET sTime = DATE_FORMAT(ADDDATE(sTime, 1), '%Y%m%d');
SET tableName = CONCAT('tbl_req_', sTime);
SELECT COUNT(1) INTO cnt
FROM information_schema.tables
WHERE table_name = tableName AND TABLE_SCHEMA = tchema;
IF cnt != 0 THEN
IF rest = 1 THEN
SET sqlVar = CONCAT(sqlVar, ' SELECT DISTINCT channel_id, app_id FROM ', tableName);
ELSE
SET sqlVar = CONCAT(sqlVar, ' SELECT DISTINCT channel_id, app_id FROM ', tableName, ' UNION');
END IF;
END IF;
SET rest = DATEDIFF(eTime, sTime);
END WHILE;
SET @v_s = sqlVar;
PREPARE stmt FROM @v_s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
-- 呼叫範例:查詢 2014-07-30 至 2014-09-30 的 biz_date 庫日誌
CALL unionSp('20140730', '20140930', 'biz_date');
ADDDATE 遞增日期,拼接 tbl_req_YYYYMMDD。information_schema.tables 確認表存在,避免報錯。UNION 會去除重複行;若需保留重複請用 UNION ALL (效能更好)。PREPARE/EXECUTE/DEALLOCATE PREPARE 執行。SELECT 欄位數必須一致,欄位型別建議一致。SELECT 為準。UNION 會排序去重,大資料量建議改 UNION ALL 後應用層去重。SELECT 權限。channel_id、app_id 加上適當索引。