A beginner's guide to PostgreSQL query syntax, with examples
Select all columns
SELECT * FROM employees;
Select specific columns
SELECT first_name, last_name, salary FROM employees;
Use column aliases
SELECT first_name AS name, last_name AS surname FROM employees;
Basic comparison operators
SELECT * FROM employees WHERE salary > 5000;
SELECT * FROM products WHERE price BETWEEN 10 AND 20;
SELECT * FROM customers WHERE country IN ('USA', 'Canada', 'UK');
Pattern matching
SELECT * FROM employees WHERE last_name LIKE 'S%';
SELECT * FROM products WHERE description LIKE '%organic%';
Handling NULL values
SELECT * FROM employees WHERE manager_id IS NULL;
SELECT * FROM orders WHERE shipping_date IS NOT NULL;
The ORDER BY clause
SELECT * FROM employees ORDER BY salary DESC;
SELECT * FROM products ORDER BY category ASC, price DESC;
LIMIT and OFFSET
SELECT * FROM employees ORDER BY salary DESC LIMIT 10;
SELECT * FROM employees ORDER BY hire_date LIMIT 5 OFFSET 10;
Common aggregate functions
SELECT COUNT(*) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MAX(price), MIN(price) FROM products;
SELECT SUM(amount) FROM orders;
Grouping with GROUP BY
SELECT department_id, COUNT(*) FROM employees GROUP BY department_id;
SELECT category, AVG(price) AS avg_price FROM products GROUP BY category;
Filtering groups with HAVING
SELECT department_id, AVG(salary) FROM employees
GROUP BY department_id HAVING AVG(salary) > 5000;
Joining tables
SELECT e.first_name, e.last_name, d.name AS department
FROM employees e
JOIN departments d ON e.department_id = d.id;
Different types of joins
-- 内连接(INNER JOIN)
SELECT c.name, o.order_date
FROM customers c
INNER JOIN orders o ON c.id = o.customer_id;
-- 左连接(LEFT JOIN)
SELECT c.name, o.order_date
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
-- 右连接(RIGHT JOIN)
SELECT e.first_name, d.name
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.id;
Working with JSON
SELECT data->>'name' AS customer_name
FROM orders WHERE data->>'status' = 'delivered';
Working with arrays
SELECT * FROM products WHERE tags @> ARRAY['organic'];
SELECT ARRAY_LENGTH(phone_numbers, 1) FROM contacts;
Full-text search
SELECT * FROM articles
WHERE to_tsvector('english', content) @@ to_tsquery('postgresql & tutorial');
String functions
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;
SELECT UPPER(name) FROM products;
SELECT LENGTH(description) FROM products;
Date functions
SELECT NOW();
SELECT DATE_TRUNC('month', order_date) AS month, COUNT(*)
FROM orders GROUP BY month;
SELECT AGE(NOW(), hire_date) FROM employees;
Basic transactions
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
Savepoints
BEGIN;
INSERT INTO orders (customer_id, amount) VALUES (1, 100);
SAVEPOINT after_order;
INSERT INTO order_items (order_id, product_id, quantity) VALUES (1, 1, 2);
ROLLBACK TO after_order;
COMMIT;
Using indexes
CREATE INDEX idx_employees_last_name ON employees (last_name);
EXPLAIN ANALYZE SELECT * FROM employees WHERE last_name = 'Smith';
Analyzing query plans
EXPLAIN ANALYZE
SELECT c.name, COUNT(o.id)
FROM customers c
JOIN orders o ON c.id = o.customer_id
GROUP BY c.name;