ShareYourGroupShareYourGroupSQL

SQL in different databases

SQL is a standard, and every database product follows most of it. Each also has its own habits, a little like regional forms of one language. This page gathers the differences that beginners meet first, so that you can take what you learn here to whichever database your college or workplace uses.

The lessons on this site run on SQLite. Nearly everything in the first eighteen lessons works unchanged everywhere. The differences cluster in a few places: limiting rows, text functions, dates, automatic id numbers and changing tables.

These notes are a guide written from general knowledge of each product. Products change with each version, so treat your database's own manual as the final word.

The five products

ProductWhat it isWhere you meet it
MySQLfree, open-source server database, owned by Oraclewebsites, web hosting, many college courses
PostgreSQLfree, open-source server databasenewer applications, data analysis
SQL ServerMicrosoft's databaseoffices that use Microsoft software
Oracle DatabaseOracle's commercial databasebanks, large companies, government systems
SQLitefree database engine that lives in a single fileinside phones, browsers and apps, and this site's practice box

MariaDB is a close relative of MySQL and shares almost all of its syntax.

The first N rows

DatabaseForm
SQLite, MySQL, PostgreSQLSELECT name FROM products ORDER BY price DESC LIMIT 3
SQL ServerSELECT TOP 3 name FROM products ORDER BY price DESC
Oracle 12c and later, PostgreSQL... ORDER BY price DESC FETCH FIRST 3 ROWS ONLY

The last form is the one in the SQL standard. SQL Server 2012 and later accepts a close relative, ORDER BY price DESC OFFSET 0 ROWS FETCH NEXT 3 ROWS ONLY. Lesson: LIMIT.

Joining text

DatabaseForm
SQLite, PostgreSQL, Oraclefirst_name || ' ' || last_name
MySQLCONCAT(first_name, ' ', last_name)
SQL Serverfirst_name + ' ' + last_name or CONCAT(...)

In MySQL, || means OR unless a setting is changed, so a query written for PostgreSQL can run there without an error and give wrong results. CONCAT also works in PostgreSQL and Oracle, though Oracle's takes only two values at a time.

Text functions

JobSQLiteMySQLPostgreSQLSQL ServerOracle
LengthLENGTHCHAR_LENGTHLENGTHLENLENGTH
Part of a textSUBSTRSUBSTRINGSUBSTRINGSUBSTRINGSUBSTR
Position of a pieceINSTRINSTRPOSITIONCHARINDEXINSTR
Replace missing valueCOALESCE, IFNULLCOALESCE, IFNULLCOALESCECOALESCE, ISNULLCOALESCE, NVL

COALESCE, UPPER, LOWER, TRIM, REPLACE and ROUND are the same everywhere. Lesson: functions.

Capital letters in comparisons

Whether 'delhi' = 'Delhi' is true depends on the product and its settings.

Database= on text, by defaultLIKE, by default
SQLitecase sensitiveignores case for A to Z
MySQLignores caseignores case
PostgreSQLcase sensitivecase sensitive (ILIKE ignores case)
SQL Serverignores caseignores case
Oraclecase sensitivecase sensitive

To be safe anywhere, compare LOWER(column) with a small-letter value.

Dates

This is where the products differ most. Lesson: dates.

JobSQLiteMySQLPostgreSQLSQL Server
Today's datedate('now')CURDATE()CURRENT_DATECAST(GETDATE() AS DATE)
Year of a datestrftime('%Y', d)YEAR(d)EXTRACT(YEAR FROM d)YEAR(d)
Add 7 daysdate(d, '+7 days')DATE_ADD(d, INTERVAL 7 DAY)d + INTERVAL '7 days'DATEADD(day, 7, d)
Days betweenjulianday(b) - julianday(a)DATEDIFF(b, a)b - aDATEDIFF(day, a, b)

Notice that DATEDIFF takes its dates in the opposite order in MySQL and SQL Server. Oracle uses SYSDATE for now, EXTRACT for parts, and plain addition of a number for days.

In every product, write a date in a query as '2026-03-15': year, month, day.

Automatic id numbers

DatabaseIn CREATE TABLE
SQLiteid INTEGER PRIMARY KEY
MySQLid INT AUTO_INCREMENT PRIMARY KEY
PostgreSQLid INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, or the older id SERIAL PRIMARY KEY
SQL Serverid INT IDENTITY(1,1) PRIMARY KEY
Oracle 12c and laterid NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY

In all of them you leave the column out of the INSERT and the number is given. Lessons: INSERT and CREATE TABLE.

Quotation marks around names

Text values take single quotation marks in every product. Names of tables and columns that contain spaces or clash with a keyword need quoting, and here the products differ.

DatabaseQuoting a name
Standard SQL, PostgreSQL, Oracle, SQLite"order date"
MySQLbackticks (the key below Esc) around the name
SQL Server[order date]

The simplest course is to avoid the need: use names in small letters with underscores, such as order_date.

Division of whole numbers

SELECT 7 / 2 gives 3 in SQLite, PostgreSQL and SQL Server, where dividing two whole numbers drops the fraction. It gives 3.5 in MySQL and Oracle. Write 7 / 2.0, or multiply by 1.0, to get decimals everywhere.

Things SQLite does differently

Because the practice box runs SQLite, it helps to know where it is more relaxed than the server databases.

None of this affects what you learn about queries. It only means that the practice box forgives a few things that a server would reject.

Features that arrived late in some products

FeatureNote
Window functionsMySQL from version 8.0; SQLite from 3.25
WITH (common table expressions)MySQL from version 8.0
INTERSECT and EXCEPTMySQL from version 8.0.31; Oracle writes MINUS for EXCEPT
FULL JOINnot in MySQL; SQLite from 3.39
SELECT without FROMOracle before version 23 needs FROM dual

If a lesson's query fails on an old server at your college, the version is the first thing to check.

Moving between products

Someone who knows SQL well in one product is productive in another within days. The ideas carry over completely: tables, keys, joins, grouping, subqueries, window functions. What changes is a short list of function names and a few keywords. When a query fails after a move:

  1. Read the error. It usually names the function or keyword that the product does not know.
  2. Look up the job, not the name. Search the new product's manual for "add days to date" and not for the old function.
  3. Check the rules on case and on whole-number division, which change results without any error.

Which one should a beginner learn?

Whichever your course or job uses. If you have a free choice, PostgreSQL and MySQL are both free and widely used, and SQLite needs no installation at all. The practice box on this site is enough for all 26 lessons.

This is an independent learning site. It is not connected with the makers of any database product. MySQL, PostgreSQL, SQL Server, Oracle and SQLite are named only so that you know where a piece of SQL works. The shop, its customers and its staff in the practice database are made up.