Come posso scomporre le espressioni ripetute in una query SQL? alias di colonna non sembrano essere il biglietto
-
04-10-2019 - |
Domanda
Quindi, ho una domanda che sembra qualcosa di simile:
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'
Se siete come me, probabilmente cominci a pensare che forse sarebbe migliorare la leggibilità e, eventualmente, le prestazioni di questa query se non stavo chiedendo a calcolare CONVERT_TZ(callTime,'+0:00','-7:00')
quattro volte separate.
Quindi cerco di creare un alias di colonna per l'espressione e sostituire altre occorrenze con quell'alias:
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'
Questo è quando ho imparato, per citare il manuale di MySQL:
standard SQL non consente riferimenti a alias di colonna in una clausola WHERE. Questo è imposto restrizione perché quando la clausola WHERE viene valutata, la valore della colonna può non aver ancora stato determinata.
Quindi, questo approccio sembrerebbe essere morto in acqua.
Come è qualcuno che scrive query con espressioni come questo suppone che fare con esso ricorrenti?
Soluzione
È possibile definire alias in una tabella derivata e poi fare riferimento nella query esterna:
SELECT callTimeZoned, callLength,
DATE_FORMAT(callTimeZoned,'%b %d %Y') as callDate,
DATE_FORMAT(callTimeZoned,'%H:%i') as callTimeOfDay
FROM (
SELECT
CONVERT_TZ(callTime,'+0:00','-7:00') as callTimeZoned,
SEC_TO_TIME(callLength) as callLength
FROM cs_calldata
WHERE customerCode='5999999-abc-blahblahblah'
) AS d
WHERE
callTimeZoned BETWEEN '2010-04-25' AND '2010-05-25'
Altri suggerimenti
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' having
callTimeZoned >= '2010-04-25' AND
callTimeZoned <= '2010-05-25'