2016-05-07 20 views
8

attualmente sto lavorando con mysql 5.7 in sviluppo e 5,6 in produzione. Ogni volta che eseguo una query con un gruppo in sviluppo ottengo qualche errore come "Codice errore: 1055. L'espressione n. 1 dell'elenco SELECT non è in GROUP BY"Esiste ANY_VALUE capacità per mysql 5.6?

Ecco la query.

SELECT c.id, c.name, i.* 
FROM countries c, images i 
WHERE i.country_id = c.id 
GROUP BY c.id; Fixed for 5.7; 

SELECT c.id, c.name, 
     ANY_VALUE(i.url) url, 
     ANY_VALUE(i.lat) lat, 
     ANY_VALUE(i.lng) lng 
    FROM countries c, images i 
WHERE i.country_id = c.id 
GROUP BY c.id; 

Per risolvere che io uso la funzione mysql dal 5,7 ANY_VALUE, ma il problema principale è che la sua non è disponibile in mysql 5.6

Quindi, se posso risolvere l'istruzione SQL per lo sviluppo mi metterò un errore produzione.

Conoscete qualche soluzione o polifill per la funzione ANY_VALUE in mysql 5.6?

+1

Perché non usare solo 'MIN' o' MAX'? – trincot

risposta

9

Si sta abusando del notorious nonstandard MySQL extension to GROUP BY. SQL standard rifiuterà sempre la tua query, perché stai citando le colonne che non sono aggregati e non sono menzionate in GROUP BY.Nel tuo sistema di sviluppo stai cercando di risolvere il problema con ANY_VALUE().

Nella produzione, è possibile disattivare la ONLY_FULL_GROUP_BY MySQL Mode. prova a fare this:

SET @mode := @@SESSION.sql_mode; 
    SET SESSION sql_mode = ''; 
    /* your query here */ 
    SET SESSION sql_mode = @mode; 

Questo permetterà di MySQL per accettare la vostra richiesta.

Ma guarda, la tua richiesta non è corretta. Quando riesci a persuaderlo a correre, restituisce una riga scelta a caso dalla tabella images. Quella sorta di indeterminatezza spesso causa confusione per gli utenti e il personale di supporto tecnico.

Perché non rendere la query migliore, quindi sceglie un'immagine particolare. Se la tabella images contiene una colonna di incremento automatico id, è possibile eseguire questa operazione per selezionare la "prima" immagine.

SELECT c.id, c.name, i.* 
    FROM countries c 
    LEFT JOIN (
     SELECT MIN(id) id, country_id 
     FROM images 
     GROUP BY country_id 
     ) first ON c.id = first.country_id 
    LEFT JOIN images i ON first.id = i.id 

Ciò restituirà una riga per paese con un'immagine prevedibile mostrata.

+0

pd: odio subselect! non sono più lenti? – Tim

+1

Suppongo che per * subselect * intendi un join per un aggregato come quello che ho. Nella mia esperienza, le loro prestazioni sono, come altre prestazioni di query, determinate dalla scelta di indici e altre cose simili. Quello che ho mostrato può velocizzare enormemente una query. Riduce il numero di righe da considerare. E la query aggregata può usare il sorprendente scan index sciolto alla sua cosa. Leggi su questo. –

7

Invece di ANY_VALUE, è possibile utilizzare le funzioni di aggregazione MIN o MAX.

In alternativa, è possibile non impostare la modalità SQL ONLY_FULL_GROUP_BY, che è impostata per impostazione predefinita per MySql 5.7, ed è responsabile della differenza con MySql 5.6. Quindi è possibile ritardare l'aggiornamento delle query fino a quando non sono stati migrati tutti gli ambienti in MySql 5.7.

Quale delle due è l'opzione migliore, è discutibile, ma a lungo termine sarà meglio adattare le query in modo che aderiscano alla regola ONLY_FULL_GROUP_BY. Usare MIN o MAX può certamente essere utile per farlo.

+0

Grazie per il tuo tempo e la tua risposta, dal wat, ANY_VALUE riferimento http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value – Tim

+0

Nel mio caso usando MAX invece di ANY_VALUE ho permesso alla mia query di funzionare sia per MySQL 5.5. e 5.7. Grazie per il suggerimento. –

3

Per decenni si potrebbe scrivere query che non erano validi in SQL standard, ma perfettamente valido mysql

In SQL standard, una query che include una clausola GROUP BY non può fare riferimento alle colonne nonaggregated nella lista di selezione che non sono nominati nella clausola GROUP BY . Ad esempio, questa interrogazione è illegale in SQL standard perché la colonna nome nonaggregated nell'elenco di selezione non si apparire nel GROUP BY:

SELEZIONA o.custid, c.name, MAX (o.payment) dagli ordini AS o, clienti AS c WHOVE o.custid = c.custid GROUP BY o.custid; Affinché la query su sia legale, la colonna nome deve essere omessa dall'elenco di selezione o denominato nella clausola GROUP BY.

MySQL estende l'utilizzo SQL standard di GROUP BY in modo che l'elenco di selezione possa fare riferimento a colonne non aggregate non denominate nella clausola GROUP BY.

Viene dalla pagina del manuale di MySql 5.6 su GROUP BY. Se guardi la stessa pagina per 5.7.6 vedi che le cose sono cambiate. E cambiato radicalmente !!

Questa pagina offre anche la soluzione. Disabilita ONLY_FULL_GROUP_BY Ciò renderà possibile che la tua vecchia query 5.6 funzioni su 5.7.6 (rimuovi ANY_VALUE dalla tua query poiché non è disponibile in 5.7.6 ma usa invece ONLY_FULL_GROUP_BY).

+1

Grazie per il tuo tempo e la risposta. – Tim

Problemi correlati