所以,我有一個查詢,看起來像這樣:如何分解SQL查詢中的重複表達式?列的別名似乎並沒有成爲售票
SELECT id,
DATE_FORMAT(CONVERT_TZ(callTime,'+0:00','-7:00'),'%b %d %Y') as callDate,
DATE_FORMAT(CONVERT_TZ(callTime,'+0:00','-7:00'),'%H:%i') as callTimeOfDay,
SEC_TO_TIME(callLength) as callLength
FROM cs_calldata WHERE
customerCode='999999-abc-blahblahblah' AND
CONVERT_TZ(callTime,'+0:00','-7:00') >= '2010-04-25' AND
CONVERT_TZ(callTime,'+0:00','-7:00') <= '2010-05-25'
如果你像我一樣,你可能會開始想,也許它會提高可讀性如果我沒有要求它計算四個不同時間的CONVERT_TZ(callTime,'+0:00','-7:00')
,可能還有這個查詢的性能。
所以我試圖創建該表達式的列別名,並與該別名替換進一步匹配的字符串
SELECT id,
CONVERT_TZ(callTime,'+0:00','-7:00') as callTimeZoned,
DATE_FORMAT(callTimeZoned,'%b %d %Y') as callDate,
DATE_FORMAT(callTimeZoned,'%H:%i') as callTimeOfDay,
SEC_TO_TIME(callLength) as callLength
FROM cs_calldata WHERE
customerCode='5999999-abc-blahblahblah' AND
callTimeZoned >= '2010-04-25' AND
callTimeZoned <= '2010-05-25'
這是當我得知,引用MySQL手冊:
標準SQL不允許在WHERE子句中引用 列別名。這 施加限制,因爲當 WHERE子句評估,該 列值可能還沒有被確定 。
所以,這種做法似乎是死在水中。
如何寫的人與經常性的這樣的表述應該對付它的查詢?
兩個問題: 1)一般:我應該擔心這最終會選擇所有的行在內部查詢中的cs_calldata中,然後使用外部過濾(這看起來效率很低),或者這是否大多數數據庫足夠聰明以創建更好的查詢計劃? 2)具體來說,MySQL是否聰明? :) – 2010-05-26 02:47:12
我不會指望MySQL結合來自內部和外部查詢的行限制,但'EXPLAIN'有助於確認這種或那種方式。至少「customerCode」的條件位於內部查詢中,因此限制了內部查詢中的函數處理的行數。 – 2010-05-26 04:18:50
1)一般不會,你不必擔心。許多RDBMS上的查詢優化器將崩潰/合併所有內容。在應用查詢的外部部分之前,使用內聯視圖不會實現。 2)具體MySQL,我不知道。 – 2010-05-26 04:21:33