Complete reference for SQL statements supported by CockroachDB
CockroachDB supports standard SQL statements for data definition, manipulation, and control. This page provides a comprehensive reference organized by statement category.
-- Basic database creationCREATE DATABASE my_app;-- With encoding and collationCREATE DATABASE international ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8';-- Conditional creationCREATE DATABASE IF NOT EXISTS my_app;
-- Rename databaseALTER DATABASE my_app RENAME TO my_application;-- Change ownerALTER DATABASE my_application OWNER TO admin_user;-- Set survival goal (multi-region)ALTER DATABASE my_app SURVIVE ZONE FAILURE;
-- Drop databaseDROP DATABASE my_app;-- Drop with cascadeDROP DATABASE my_app CASCADE;-- Conditional dropDROP DATABASE IF EXISTS my_app CASCADE;
-- Standard indexCREATE INDEX ON users (email);-- Named indexCREATE INDEX users_email_idx ON users (email);-- Composite indexCREATE INDEX users_name_email_idx ON users (last_name, first_name, email);-- Unique indexCREATE UNIQUE INDEX ON users (username);-- Partial indexCREATE INDEX active_users_idx ON users (email) WHERE status = 'active';-- Inverted index (for JSONB)CREATE INVERTED INDEX ON logs (metadata);-- Concurrent index creationCREATE INDEX CONCURRENTLY ON large_table (column_name);
-- Create sequenceCREATE SEQUENCE customer_id_seq START WITH 1000 INCREMENT BY 1;-- Use in tableCREATE TABLE customers ( id INT PRIMARY KEY DEFAULT nextval('customer_id_seq'), name TEXT NOT NULL);-- Alter sequenceALTER SEQUENCE customer_id_seq RESTART WITH 2000;ALTER SEQUENCE customer_id_seq INCREMENT BY 10;-- Drop sequenceDROP SEQUENCE customer_id_seq;
CREATE VIEW active_users AS SELECT id, username, email FROM users WHERE status = 'active';CREATE OR REPLACE VIEW user_summary AS SELECT u.id, u.username, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.username;
-- Select all columnsSELECT * FROM users;-- Select specific columnsSELECT id, username, email FROM users;-- With aliasesSELECT id AS user_id, username AS user_name, email AS contact_emailFROM users;
-- Basic filteringSELECT * FROM users WHERE status = 'active';-- Multiple conditionsSELECT * FROM users WHERE status = 'active' AND created_at > '2025-01-01';-- IN clauseSELECT * FROM users WHERE id IN (1, 2, 3, 5, 8);-- Pattern matchingSELECT * FROM users WHERE email LIKE '%@example.com';-- Range querySELECT * FROM orders WHERE total BETWEEN 100 AND 1000;
-- INNER JOINSELECT u.username, o.order_id, o.totalFROM users uINNER JOIN orders o ON u.id = o.user_id;-- LEFT JOINSELECT u.username, COUNT(o.id) AS order_countFROM users uLEFT JOIN orders o ON u.id = o.user_idGROUP BY u.id, u.username;-- Multiple joinsSELECT u.username, o.order_id, oi.item_id, oi.quantityFROM users uINNER JOIN orders o ON u.id = o.user_idINNER JOIN order_items oi ON o.id = oi.order_id;
-- Basic aggregationSELECT COUNT(*) AS total_users, COUNT(DISTINCT email) AS unique_emailsFROM users;-- GROUP BYSELECT status, COUNT(*) AS user_count, AVG(age) AS avg_ageFROM usersGROUP BY status;-- HAVING clauseSELECT user_id, COUNT(*) AS order_count, SUM(total) AS total_spentFROM ordersGROUP BY user_idHAVING COUNT(*) > 5;
-- ORDER BYSELECT * FROM users ORDER BY created_at DESC;-- Multiple sort columnsSELECT * FROM users ORDER BY last_name ASC, first_name ASC;-- LIMIT and OFFSETSELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20;-- Pagination patternSELECT * FROM users WHERE id > 100ORDER BY id LIMIT 50;
-- Basic updateUPDATE users SET status = 'inactive' WHERE id = 1;-- Update multiple columnsUPDATE users SET status = 'active', last_login = CURRENT_TIMESTAMPWHERE id = 1;-- Update with subqueryUPDATE ordersSET status = 'shipped'WHERE id IN ( SELECT order_id FROM shipments WHERE shipped_at IS NOT NULL);-- Update with join patternUPDATE orders oSET total = ( SELECT SUM(price * quantity) FROM order_items oi WHERE oi.order_id = o.id);-- RETURNING clauseUPDATE users SET status = 'active'WHERE id = 1RETURNING id, status, updated_at;
-- Basic deleteDELETE FROM users WHERE id = 1;-- Delete with conditionDELETE FROM sessionsWHERE expires_at < CURRENT_TIMESTAMP;-- Delete with subqueryDELETE FROM order_itemsWHERE order_id IN ( SELECT id FROM orders WHERE status = 'cancelled');-- RETURNING clauseDELETE FROM users WHERE status = 'deleted'RETURNING id, username;
-- Show query planEXPLAIN SELECT * FROM users WHERE email = '[email protected]';-- Verbose outputEXPLAIN (VERBOSE) SELECT * FROM orders o JOIN users u ON o.user_id = u.id;-- Analyze actual executionEXPLAIN ANALYZE SELECT COUNT(*) FROM large_table;