Estou tendo um problema com uma consulta bastante complexa em que preciso armazenar os IDs de uma tabela (com base em critérios pesados) em uma tabela alternativa estreita para referência futura, mas continuo encontrando um erro de construção de sql ruim.
Se eu executar a seguinte consulta sozinha, ela funcionará bem:
(SELECT DISTINCT a.id FROM accounts AS a
WHERE a.createdate >= date_sub(now(), INTERVAL 1 YEAR)
AND a.email NOT LIKE '%gmail.com')
UNION DISTINCT
(SELECT DISTINCT a.id FROM accounts AS a
WHERE a.createdate < date_sub(now(), INTERVAL 1 YEAR)
AND a.email NOT LIKE '%yahoo.com') AND a.email NOT IN
(SELECT email FROM inactive_clients));
No entanto, se eu tentar executar a mesma consulta assim:
INSERT INTO my_backup_table (account_id) VALUES ($aboveQuery);
Estou tendo o erro a seguir:
MySQL server version for the right syntax to use near 'UNION DISTINCT (SELECT DISTINCT a.id FROM accounts at line 1
Eu tentei qualquer número de permutações entre parênteses e ainda recebi o mesmo erro.
Você não pode usar a
INSERT INTO tblname (...) VALUES ...
sintaxeVocê deve usar a
INSERT INTO tblname (...) SELECT ...
sintaxeTente o seguinte:
Rolando respondeu sua pergunta sobre a
INSERT
sintaxe, mas gostaria de acrescentar alguns comentários adicionais sobre o desempenho desta consulta. Primeiro, você está DISTINTO muitas vezes. Na verdade, você não precisaDISTINCT
de nenhum lugar nesta consulta, comoUNION
implicaDISTINCT
. Não tenho certeza se o otimizador eliminará osDISTINCT
s desnecessários, mas considere o seguinte:Além disso,
NOT IN (SELECT)
executará a consulta interna para cada linha na consulta delimitadora e é altamente ineficiente. Eu me deparo com isso semanalmente com desenvolvedores da minha equipe e sempre causa problemas. Em vez disso, reescreva a consulta como um arquivoLEFT JOIN
. Você também obterá um impacto no desempenho do unindexableLIKE %domain.com
.Outra consideração é que, como essa consulta provavelmente levará um "tempo", no nível de isolamento de transação padrão do MySQL de REPEATABLE READ, muitas das linhas nas tabelas na
SELECT
instrução serão bloqueadas devido a bloqueios de lacunas, portanto, não serão atualizáveis. Por esse motivo, sugiro que você execute essa consulta em READ-COMMITTED combinada com replicação baseada em MIXED ou ROW.Espero que isso ajude um pouco.