首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 視圖查詢順序導致結果不一致的奇怪現象分析

     編輯:MySQL 綜合教學

MySQL 視圖查詢順序導致結果不一致的奇怪現象分析

MySQL 5.6.14 中發現:對同一視圖執行 SELECT MERGED_FLAG FROM vw_fdmt_is_test 與 SELECT MERGED_FLAG FROM vw_fdmt_is_test ORDER BY END_DATE DESC 返回的 MERGED_FLAG 值竟然不同(一個為字符 '1',一個為數字 1)。

重現腳本

DROP TABLE IF EXISTS fdmt_is_merg_test;
CREATE TABLE fdmt_is_merg_test (
    ID BIGINT(20) NOT NULL AUTO_INCREMENT,
    TICKER_SYMBOL VARCHAR(10) DEFAULT NULL,
    END_DATE DATE NOT NULL,
    PRIMARY KEY (ID),
    KEY edate (END_DATE, TICKER_SYMBOL),
    KEY ix_ticker (TICKER_SYMBOL)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO fdmt_is_merg_test(TICKER_SYMBOL, END_DATE) VALUES 
('000002','2006-03-30'),('000002','2006-03-31');

DROP TABLE IF EXISTS md_security_test;
CREATE TABLE md_security_test (
    SECURITY_ID BIGINT(20) NOT NULL,
    TICKER_SYMBOL VARCHAR(10) NOT NULL,
    DYID VARCHAR(50) DEFAULT NULL,
    PRIMARY KEY (SECURITY_ID),
    UNIQUE KEY UK_DYID (DYID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO md_security_test(SECURITY_ID, TICKER_SYMBOL, DYID) VALUES 
(0,'000002','000002.XSHE');

DROP VIEW IF EXISTS vw_fdmt_is_test;
CREATE VIEW vw_fdmt_is_test AS
SELECT a.TICKER_SYMBOL, b.DYID AS SECURITY_ID, a.END_DATE,
       '1' AS MERGED_FLAG, 1 AS MERGED_FLAG_int
FROM fdmt_is_merg_test a JOIN md_security_test b 
ON a.TICKER_SYMBOL = b.TICKER_SYMBOL;

現象

  • SELECT MERGED_FLAG FROM vw_fdmt_is_test; → 返回 '1' (字符)
  • SELECT MERGED_FLAG FROM vw_fdmt_is_test ORDER BY END_DATE DESC; → 返回 1 (數字)

原因分析

MySQL 視圖合併算法在處理 ORDER BY 時可能改變欄位類型推導邏輯,導致常量 '1' 被隱式轉換為數字。這屬於優化器在不同執行計劃下類型推導不一致的 Bug。

解決建議

  1. 明確指定欄位類型:CAST('1' AS CHAR) AS MERGED_FLAG
  2. 升級 MySQL 版本(5.7+ / 8.0 已修復類似問題)
  3. 避免在視圖中混用字符/數字常量作為同名欄位

結論: 視圖定義時應盡量顯式轉換常量類型,避免依賴隱式推導。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved