Skip to main content
RapidDev - Software Development Agency
supabase-tutorial

How to Write SQL Queries in the Supabase SQL Editor

The Supabase SQL Editor is a built-in browser tool in the Dashboard where you can write and run any PostgreSQL query directly against your database. Open it from the left sidebar, type your SQL, and click Run or press Cmd+Enter. You can save queries as snippets, export results to CSV, browse your schema, and use it for everything from creating tables to debugging RLS policies.

What you'll learn

  • How to open and navigate the SQL Editor in the Supabase Dashboard
  • How to write and run SELECT, INSERT, UPDATE, and DELETE queries
  • How to save queries as reusable snippets and export results to CSV
  • How to use the schema browser to explore your tables and columns
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner9 min read10-15 minSupabase (all plans), Dashboard SQL EditorMarch 2026RapidDev Engineering Team
TL;DR

The Supabase SQL Editor is a built-in browser tool in the Dashboard where you can write and run any PostgreSQL query directly against your database. Open it from the left sidebar, type your SQL, and click Run or press Cmd+Enter. You can save queries as snippets, export results to CSV, browse your schema, and use it for everything from creating tables to debugging RLS policies.

Using the SQL Editor in the Supabase Dashboard

The SQL Editor is one of the most powerful tools in the Supabase Dashboard. It gives you direct PostgreSQL access without needing a terminal or external database client. You can create tables, write complex queries, debug Row Level Security policies, manage indexes, and run migrations — all from your browser. This tutorial walks you through the full workflow from opening the editor to saving and exporting your queries.

Prerequisites

  • A Supabase project (free tier works)
  • Access to the Supabase Dashboard at app.supabase.com
  • Basic understanding of SQL syntax (SELECT, INSERT, UPDATE, DELETE)

Step-by-step guide

1

Open the SQL Editor in the Dashboard

Log in to your Supabase Dashboard at app.supabase.com and select your project. In the left sidebar, click the SQL Editor icon (it looks like a terminal/code icon). This opens the SQL Editor view with a blank query tab. You can have multiple query tabs open at once — each tab is an independent query workspace. The left panel shows your saved snippets and quickstart templates provided by Supabase.

Expected result: The SQL Editor opens with a blank query tab and a blinking cursor ready for input.

2

Write and run your first SELECT query

Type a SQL query in the editor area. Start with a simple SELECT to verify your setup. Click the green Run button in the top-right corner or press Cmd+Enter (Mac) / Ctrl+Enter (Windows) to execute. The results appear in a table below the editor. You can sort columns by clicking their headers and resize columns by dragging the borders. If your query has an error, the error message appears in red below the editor with the line number and description.

typescript
1-- List all tables in the public schema
2SELECT table_name, table_type
3FROM information_schema.tables
4WHERE table_schema = 'public'
5ORDER BY table_name;
6
7-- Query data from a specific table
8SELECT *
9FROM your_table_name
10LIMIT 20;

Expected result: A results table appears below the editor showing the query output with column headers and row data.

3

Use the schema browser to explore tables and columns

On the left side of the SQL Editor, switch to the schema browser panel. This shows all schemas (public, auth, storage, etc.) and the tables within each schema. Expand a table to see its columns, data types, and constraints. This is invaluable when you need to check column names or data types before writing a query. You can also see indexes, triggers, and foreign key relationships directly in the browser.

typescript
1-- You can also explore your schema with SQL
2SELECT column_name, data_type, is_nullable, column_default
3FROM information_schema.columns
4WHERE table_schema = 'public'
5 AND table_name = 'your_table_name'
6ORDER BY ordinal_position;

Expected result: The schema browser displays your tables, columns, and their data types in a tree view.

4

Create a table using the SQL Editor

The SQL Editor is the recommended way to create tables when you need precise control over data types, constraints, and defaults. Write a CREATE TABLE statement, enable Row Level Security immediately after creation, and add at least one RLS policy so the table is accessible via the API. Always enable RLS on any table exposed through the public schema — without it, anyone with your anon key can read all data.

typescript
1-- Create a tasks table
2CREATE TABLE public.tasks (
3 id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
4 user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
5 title text NOT NULL,
6 completed boolean DEFAULT false,
7 created_at timestamptz DEFAULT now()
8);
9
10-- Enable Row Level Security
11ALTER TABLE public.tasks ENABLE ROW LEVEL SECURITY;
12
13-- Allow users to read their own tasks
14CREATE POLICY "Users can view own tasks"
15 ON public.tasks FOR SELECT
16 TO authenticated
17 USING ((SELECT auth.uid()) = user_id);
18
19-- Allow users to insert their own tasks
20CREATE POLICY "Users can create tasks"
21 ON public.tasks FOR INSERT
22 TO authenticated
23 WITH CHECK ((SELECT auth.uid()) = user_id);

Expected result: The table is created with RLS enabled and policies applied. You can verify by checking the Table Editor in the Dashboard sidebar.

5

Save queries as reusable snippets

After writing a query you want to reuse, click the Save button (or use Cmd+S) to save it as a snippet. Give it a descriptive name like 'List active users' or 'Monthly revenue report'. Saved snippets appear in the left panel under your personal snippets. You can also create folders to organize them. Snippets are saved per-user, not per-project, so only you can see your saved queries. To share a query with your team, copy the SQL and share it as a migration file instead.

Expected result: Your query appears in the saved snippets panel and can be opened in a new tab at any time.

6

Export query results to CSV

After running a query, you can export the results by clicking the Download button (downward arrow icon) above the results table. This exports the current result set as a CSV file. This is useful for sharing data with non-technical team members, creating reports, or backing up small datasets. For large exports (millions of rows), use pg_dump from the command line instead — the SQL Editor export works best for result sets under 100,000 rows.

typescript
1-- Example: Export all users who signed up this month
2SELECT
3 id,
4 email,
5 created_at,
6 raw_user_meta_data->>'first_name' AS first_name
7FROM auth.users
8WHERE created_at >= date_trunc('month', CURRENT_DATE)
9ORDER BY created_at DESC;

Expected result: A CSV file downloads to your computer containing the query results with column headers.

Complete working example

sql-editor-examples.sql
1-- =============================================
2-- Supabase SQL Editor: Common Query Examples
3-- =============================================
4
5-- 1. Create a table with proper constraints
6CREATE TABLE public.projects (
7 id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
8 user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
9 name text NOT NULL CHECK (char_length(name) > 0),
10 description text,
11 status text DEFAULT 'active' CHECK (status IN ('active', 'archived', 'deleted')),
12 created_at timestamptz DEFAULT now(),
13 updated_at timestamptz DEFAULT now()
14);
15
16-- 2. Enable RLS (always do this for public tables)
17ALTER TABLE public.projects ENABLE ROW LEVEL SECURITY;
18
19-- 3. Create RLS policies
20CREATE POLICY "Users can view own projects"
21 ON public.projects FOR SELECT TO authenticated
22 USING ((SELECT auth.uid()) = user_id);
23
24CREATE POLICY "Users can insert own projects"
25 ON public.projects FOR INSERT TO authenticated
26 WITH CHECK ((SELECT auth.uid()) = user_id);
27
28CREATE POLICY "Users can update own projects"
29 ON public.projects FOR UPDATE TO authenticated
30 USING ((SELECT auth.uid()) = user_id)
31 WITH CHECK ((SELECT auth.uid()) = user_id);
32
33CREATE POLICY "Users can delete own projects"
34 ON public.projects FOR DELETE TO authenticated
35 USING ((SELECT auth.uid()) = user_id);
36
37-- 4. Add an index for faster queries
38CREATE INDEX idx_projects_user_id ON public.projects (user_id);
39
40-- 5. Create an auto-update trigger for updated_at
41CREATE OR REPLACE FUNCTION public.update_updated_at()
42RETURNS TRIGGER
43LANGUAGE plpgsql
44AS $$
45BEGIN
46 NEW.updated_at = now();
47 RETURN NEW;
48END;
49$$;
50
51CREATE TRIGGER set_updated_at
52 BEFORE UPDATE ON public.projects
53 FOR EACH ROW
54 EXECUTE FUNCTION public.update_updated_at();
55
56-- 6. Query with filters and joins
57SELECT
58 p.id,
59 p.name,
60 p.status,
61 p.created_at,
62 u.email AS owner_email
63FROM public.projects p
64JOIN auth.users u ON u.id = p.user_id
65WHERE p.status = 'active'
66ORDER BY p.created_at DESC
67LIMIT 50;

Common mistakes when writing SQL Queries in the Supabase SQL Editor

Why it's a problem: Forgetting to enable RLS after creating a table in the SQL Editor

How to avoid: Always add ALTER TABLE your_table ENABLE ROW LEVEL SECURITY immediately after CREATE TABLE. Without RLS, anyone with your anon key can read and modify all rows.

Why it's a problem: Running destructive queries (DROP TABLE, DELETE without WHERE) without a backup

How to avoid: Always run a SELECT with the same WHERE clause first to preview which rows will be affected. For DROP operations, consider renaming the table first as a soft-delete.

Why it's a problem: Trying to modify the auth schema directly (INSERT INTO auth.users)

How to avoid: Use the Supabase Auth API (supabase.auth.signUp, supabase.auth.admin.createUser) instead. The auth schema is managed by GoTrue and direct modification can break authentication.

Why it's a problem: Writing queries that reference non-existent columns because of a typo

How to avoid: Use the schema browser to verify column names before writing queries. Column names in Supabase are case-sensitive if quoted — prefer lowercase_with_underscores and never quote identifiers.

Best practices

  • Always enable RLS on every table in the public schema and create appropriate policies before using the table in production
  • Use the SELECT preview technique before running UPDATE or DELETE — write a SELECT with the same WHERE clause first
  • Save frequently used queries as snippets so you do not have to rewrite them each time
  • Add comments to your SQL queries explaining what they do and why, especially for complex JOINs and RLS policies
  • Use LIMIT when exploring large tables to avoid loading millions of rows into the editor
  • Prefer gen_random_uuid() for primary keys in new tables — it avoids sequential ID enumeration attacks
  • Create indexes on columns used in WHERE clauses and RLS policies to keep queries fast
  • Use transactions (BEGIN; ... COMMIT;) when running multiple related changes to ensure atomicity

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I need to write a SQL query in the Supabase SQL Editor that creates a table for blog posts with a title, body, author (linked to auth.users), published status, and timestamps. Include RLS policies so users can only see and edit their own posts. Show the complete SQL.

Supabase Prompt

Write a SQL query in the Supabase SQL Editor to create a blog_posts table with columns for id (UUID), user_id (foreign key to auth.users), title (text), body (text), is_published (boolean), and created_at (timestamptz). Enable RLS and add policies for authenticated users to CRUD their own posts.

Frequently asked questions

Can I run multiple SQL statements in one query tab?

Yes. Separate statements with semicolons and click Run to execute all of them in order. You can also highlight a single statement and press Cmd+Enter to run only that statement.

Is there a query size or result limit in the SQL Editor?

The SQL Editor works best with result sets under 100,000 rows. For larger exports, use pg_dump from the CLI. There is no hard query size limit, but very long queries may time out after 60 seconds on the free plan.

Can I access the auth.users table from the SQL Editor?

Yes, you can SELECT from auth.users in the SQL Editor to inspect user data. However, never INSERT, UPDATE, or DELETE rows in auth.users directly — use the Supabase Auth API or the Dashboard Authentication panel instead.

How do I undo a query I ran by mistake?

SQL queries in the editor are not automatically reversible. For DML changes (INSERT, UPDATE, DELETE), you would need a backup or point-in-time recovery (Pro plan). For DDL changes (DROP TABLE), restore from a backup. Always test destructive queries on a local Supabase instance first.

Can I use the SQL Editor to debug Row Level Security policies?

Yes. You can test RLS by running queries as different roles. Use SET ROLE authenticated followed by SET request.jwt.claims to simulate a specific user. This helps verify that policies return the correct rows.

Does the SQL Editor support autocomplete?

The SQL Editor provides basic autocomplete for SQL keywords and table names. It is not as advanced as desktop tools like DataGrip, but it covers common use cases. Use the schema browser alongside the editor for column name reference.

Can RapidDev help me write complex SQL queries for my Supabase project?

Yes. RapidDev's engineering team can help you design database schemas, write complex queries, set up RLS policies, and optimize performance for your Supabase project.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.