Diferenças de dialetos SQL: o que muda entre bancos de dados

SELECT, WHERE, GROUP BY, JOIN e CASE funcionam igual em todos os grandes bancos. As diferenças estão nos detalhes ao redor. Os exemplos rodam no PostgreSQL, que este site usa; cada seção indica como os outros fazem.

Limitar o número de linhas

PostgreSQL, MySQL e SQLite usam LIMIT (com OFFSET para pular linhas). O SQL Server usa SELECT TOP n, ou OFFSET ... FETCH depois do ORDER BY. O Oracle 12c e versões mais novas, e também o PostgreSQL, aceitam o padrão FETCH FIRST n ROWS ONLY.

SELECT name, unit_price
FROM products
ORDER BY unit_price DESC
FETCH FIRST 3 ROWS ONLY;

Resultado: Os três produtos mais caros, usando a sintaxe padrão que PostgreSQL e Oracle compartilham.

Juntar textos

PostgreSQL, SQLite e Oracle juntam textos com ||. O SQL Server usa + (ou CONCAT). No MySQL, || significa OR, a não ser que uma configuração seja alterada, então use CONCAT(). CONCAT funciona no PostgreSQL, no MySQL e no SQL Server e é a opção mais portável.

SELECT CONCAT(first_name, ' ', last_name) AS full_name
FROM customers
ORDER BY customer_id;

Resultado: O nome completo de cada cliente.

Data de hoje

O PostgreSQL tem CURRENT_DATE e NOW(). O MySQL tem CURDATE() e NOW(). O SQL Server tem GETDATE(). O SQLite usa date('now'). O Oracle usa SYSDATE. CURRENT_DATE é SQL padrão e funciona no PostgreSQL, no MySQL e no Oracle.

SELECT CURRENT_DATE AS today;

Resultado: Uma linha com a data de hoje.

Divisão inteira

No PostgreSQL, no SQL Server e no SQLite, 7 / 2 é 3 quando os dois números são inteiros. No MySQL e no Oracle é 3.5. Para ter o mesmo resultado em todos, converta primeiro um dos lados para um tipo decimal.

SELECT 7 / 2 AS integer_division, 7 / 2.0 AS with_decimal;

Resultado: 3 e 3.5 no PostgreSQL.

Juntar os valores de um grupo

STRING_AGG existe no PostgreSQL e no SQL Server 2017 e versões mais novas. MySQL e SQLite a chamam de GROUP_CONCAT. O Oracle a chama de LISTAGG.

SELECT city, STRING_AGG(first_name, ', ' ORDER BY first_name) AS names
FROM customers
GROUP BY city
ORDER BY city;

Resultado: Os clientes de cada cidade em um único texto.

Maiúsculas, aspas e numeração automática

Comparação de texto: o LIKE do PostgreSQL diferencia maiúsculas de minúsculas (use ILIKE para o oposto); MySQL e SQL Server geralmente comparam texto sem diferenciar maiúsculas por padrão, dependendo da collation; o LIKE do SQLite ignora maiúsculas para letras simples do inglês.

Citar um nome: o SQL padrão usa aspas duplas, como PostgreSQL, Oracle e SQLite. MySQL usa crases e SQL Server usa colchetes.

Numeração automática de uma chave: PostgreSQL usa GENERATED ... AS IDENTITY (ou serial), MySQL usa AUTO_INCREMENT, SQL Server usa IDENTITY(1,1), SQLite usa INTEGER PRIMARY KEY e Oracle 12c e versões mais novas usam GENERATED AS IDENTITY.

SELECT name FROM products WHERE name ILIKE 'CROISSANT';

Resultado: O Croissant, encontrado apesar das letras maiúsculas, porque o ILIKE ignora a diferença entre maiúsculas e minúsculas.

Perguntas comuns

Qual banco de dados devo aprender primeiro?
Qualquer um. O núcleo se transfere quase por completo. O PostgreSQL segue o padrão de perto, o que o torna uma boa primeira escolha.
Minhas consultas deste site vão rodar no MySQL ou no SQL Server?
A maioria das básicas vai. As partes a mudar são as deste guia: LIMIT, ILIKE, ||, funções de data, STRING_AGG e a cláusula RETURNING.

Pratique