Skip to content
LAM
Read Home Blog
Make Projects HTML Tools Games
Touch grass Notes Resume Links
Home Blog HTML Projects
Tools Games Notes Resume Links
Back SQLite3 Expert Cheat Sheet Programming
Download Open
Show description 2,401 chars · Programming

SQLite3 Expert Cheat Sheet

SQLite3 Expert Cheat Sheet





SQLite3 • Pro Cheat Sheet

SQLite3: Commands, Patterns, and Interactive Builder





Navigate

Basics
Inspect DB
Querying
Import / Export
Schema & Migrations
Indexes & Perf
FTS5 & JSON1
Transactions
Explain / Analyze
Backups & Safety
One‑Liners
Interactive Builder




Basics

CLI.metaSQL

Copy$ sqlite3 my.db
sqlite> .help -- show meta-commands
sqlite> .quit


Common meta‑commands (.tables, .schema, headers, modes)
Copysqlite> .tables -- list tables
sqlite> .schema open_mics -- show CREATE TABLE
sqlite> .headers on -- include column names
sqlite> .mode column -- pretty tabular
sqlite> .mode csv -- csv output
sqlite> .separator \t -- switch delimiter
sqlite> .output result.csv -- send output to file
sqlite> .output stdout -- back to screen







Inspect the Database

Copysqlite> PRAGMA database_list; -- attached dbs & paths
sqlite> .tables -- tables & views
sqlite> PRAGMA table_info(open_mics); -- columns
sqlite> PRAGMA foreign_key_list(t); -- fkeys on table t



Tip: If a table seems “missing,” verify you’re opening the correct file using PRAGMA database_list; and check the path.






Querying Essentials

CopySELECT state, city, venue, address, day, time, recurring, description
FROM open_mics;


Filters, Sorting, Limits
CopySELECT *
FROM open_mics
WHERE state='CA' AND day IN ('sunday','monday')
ORDER BY city, time
LIMIT 50;



Computed Columns & CASE
CopySELECT venue,
CASE WHEN recurring IN (1,'1','true','TRUE') THEN 'Yes' ELSE 'No' END AS recurring_text
FROM open_mics;



Joins & Aggregates
SELECT state, COUNT(*) AS shows
FROM open_mics
GROUP BY state
ORDER BY shows DESC;



Window Functions (SQLite ≥ 3.25)
SELECT state, city, venue,
ROW_NUMBER() OVER (PARTITION BY state ORDER BY city) rn
FROM open_mics;






Import / Export


Copy$ sqlite3 -header -csv open_mics.db \
"SELECT state, city, venue, address, day, time, recurring, description FROM open_mics;"
> openmics.csv

Copy$ sqlite3 my.db
sqlite> .mode csv
sqlite> .import data.csv open_mics




TSV & Pretty Table
Copy$ sqlite3 -header -separator $'\t' open_mics.db \
"SELECT * FROM open_mics LIMIT 20;" > sample.tsv






Schema & Migrations

CREATE TABLE open_mics (
id INTEGER PRIMARY KEY,
source TEXT NOT NULL,
state TEXT, city TEXT, venue TEXT,
address TEXT,…

SQLite3 Expert Cheat Sheet

21,036 bytes · HTML source
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SQLite3 Expert Cheat Sheet</title>
<style>
  :root{
    --bg:#0b1020; --panel:#111833; --ink:#e7ecff; --muted:#9fb0ff; --accent:#7aa2ff; --good:#0edc8d; --warn:#ffd166; --bad:#ff5d73; --code:#0a0f1f; --border:#233055;
  }
  *{box-sizing:border-box}
  html,body{height:100%}
  body{margin:0;background:linear-gradient(180deg, #0a0f1f, #0b1020 30%, #0b0f21);font:16px/1.5 ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,"Helvetica Neue",Arial;color:var(--ink)}
  .wrap{max-width:1100px;margin:0 auto;padding:28px}
  header{display:flex;gap:16px;align-items:center;margin-bottom:20px}
  .badge{padding:4px 10px;border:1px solid var(--border);border-radius:999px;color:var(--muted);background:#0d1430}
  h1{font-size:28px;margin:0}
  .grid{display:grid;grid-template-columns:280px 1fr;gap:18px}
  nav{position:sticky;top:16px;align-self:start;background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:14px}
  nav h3{margin:6px 0 8px;font-size:14px;color:var(--muted)}
  nav a{display:block;padding:8px 10px;border-radius:10px;color:var(--ink);text-decoration:none}
  nav a:hover{background:#0e1433}
  .section{background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:18px;margin-bottom:18px}
  .section h2{margin-top:0}
  .k{color:#9cdcfe}
  .v{color:#ce9178}
  .sql{background:var(--code);border:1px solid var(--border);padding:14px;border-radius:10px;overflow:auto;position:relative}
  .shell{background:#0d142a;border:1px solid var(--border);padding:14px;border-radius:10px;overflow:auto;position:relative}
  code, pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:13.5px}
  .btn{cursor:pointer;border:none;border-radius:10px;padding:8px 12px;background:#12204b;color:#dbe7ff;border:1px solid var(--border);}
  .btn:hover{filter:brightness(1.1)}
  .btn.small{padding:6px 8px;font-size:12px}
  .row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
  .copy{position:absolute;top:8px;right:8px}
  .pill{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;border:1px solid var(--border);color:var(--muted)}
  .kbd{padding:2px 6px;border-radius:6px;border:1px solid var(--border);background:#0a122a;color:#cfe1ff}
  details{border:1px dashed var(--border);border-radius:10px;padding:10px;margin:8px 0}
  details[open]{background:#0d1532}
  .callout{border-left:4px solid var(--accent);padding:10px 12px;background:#0c1430;border-radius:10px}
  .good{border-color:var(--good)}.warn{border-color:var(--warn)}.bad{border-color:var(--bad)}
  .tag{margin-left:6px}
  .search{width:100%;padding:10px;border-radius:10px;border:1px solid var(--border);background:#0c1430;color:var(--ink)}
  .hl{background:#1b254a;border-radius:6px;padding:0 4px}
  .table{border-collapse:collapse;width:100%;overflow:auto}
  .table th,.table td{border-bottom:1px solid var(--border);padding:8px 6px;text-align:left}
  .footer{opacity:.8;font-size:12px;margin-top:20px}
  /* Builder */
  .builder{display:grid;grid-template-columns:1fr 1fr;gap:14px}
  .card{background:#0c1430;border:1px solid var(--border);border-radius:12px;padding:12px}
  label{font-size:12px;color:var(--muted)}
  input[type=text], textarea, select{width:100%;padding:8px;border-radius:10px;border:1px solid var(--border);background:#0a122a;color:var(--ink)}
  textarea{min-height:110px}
  .cmdout{white-space:pre-wrap}
</style>
</head>
<body>
  <div class="wrap">
    <header>
      <div class="badge">SQLite3 • Pro Cheat Sheet</div>
      <h1>SQLite3: Commands, Patterns, and Interactive Builder</h1>
    </header>
    <div class="grid">
      <nav>
        <h3>Navigate</h3>
        <a href="#basics">Basics</a>
        <a href="#inspect">Inspect DB</a>
        <a href="#query">Querying</a>
        <a href="#import-export">Import / Export</a>
        <a href="#schema">Schema & Migrations</a>
        <a href="#indexes">Indexes & Perf</a>
        <a href="#fts-json">FTS5 & JSON1</a>
        <a href="#tx">Transactions</a>
        <a href="#explain">Explain / Analyze</a>
        <a href="#security">Backups & Safety</a>
        <a href="#one-liners">One‑Liners</a>
        <a href="#builder">Interactive Builder</a>
      </nav>

      <main>
        <section id="basics" class="section">
          <h2>Basics</h2>
          <div class="row"><span class="pill">CLI</span><span class="pill">.meta</span><span class="pill">SQL</span></div>
          <div class="shell"><button class="btn small copy" data-copy="sqlite3 my.db">Copy</button><pre>$ <span class="k">sqlite3</span> <span class="v">my.db</span>
sqlite&gt; <span class="k">.help</span>                -- show meta-commands
sqlite&gt; <span class="k">.quit</span>
</pre></div>
          <details><summary><strong>Common meta‑commands</strong> (<code>.tables</code>, <code>.schema</code>, headers, modes)</summary>
            <div class="shell"><button class="btn small copy" data-copy=".tables">Copy</button><pre>sqlite&gt; <span class="k">.tables</span>               -- list tables
sqlite&gt; <span class="k">.schema</span> open_mics      -- show CREATE TABLE
sqlite&gt; <span class="k">.headers</span> on            -- include column names
sqlite&gt; <span class="k">.mode</span> column           -- pretty tabular
sqlite&gt; <span class="k">.mode</span> csv              -- csv output
sqlite&gt; <span class="k">.separator</span> \t          -- switch delimiter
sqlite&gt; <span class="k">.output</span> result.csv     -- send output to file
sqlite&gt; <span class="k">.output</span> stdout         -- back to screen
</pre></div>
          </details>
        </section>

        <section id="inspect" class="section">
          <h2>Inspect the Database</h2>
          <div class="shell"><button class="btn small copy" data-copy="PRAGMA database_list;">Copy</button><pre>sqlite&gt; <span class="k">PRAGMA</span> database_list;     -- attached dbs & paths
sqlite&gt; <span class="k">.tables</span>                     -- tables & views
sqlite&gt; <span class="k">PRAGMA</span> table_info(open_mics); -- columns
sqlite&gt; <span class="k">PRAGMA</span> foreign_key_list(t);  -- fkeys on table t
</pre></div>
          <div class="callout">
            Tip: If a table seems “missing,” verify you’re opening the correct file using <code>PRAGMA database_list;</code> and check the path.
          </div>
        </section>

        <section id="query" class="section">
          <h2>Querying Essentials</h2>
          <div class="sql"><button class="btn small copy" data-copy="SELECT state, city, venue, address, day, time, recurring, description FROM open_mics;">Copy</button><pre><span class="k">SELECT</span> state, city, venue, address, day, time, recurring, description
<span class="k">FROM</span> open_mics;</pre></div>
          <details open>
            <summary><strong>Filters, Sorting, Limits</strong></summary>
            <div class="sql"><button class="btn small copy" data-copy="SELECT * FROM open_mics WHERE state='CA' AND day IN ('sunday','monday') ORDER BY city, time LIMIT 50;">Copy</button><pre><span class="k">SELECT</span> *
<span class="k">FROM</span> open_mics
<span class="k">WHERE</span> state=<span class="v">'CA'</span> <span class="k">AND</span> day <span class="k">IN</span> (<span class="v">'sunday'</span>,<span class="v">'monday'</span>)
<span class="k">ORDER BY</span> city, time
<span class="k">LIMIT</span> 50;</pre></div>
          </details>
          <details>
            <summary><strong>Computed Columns & CASE</strong></summary>
            <div class="sql"><button class="btn small copy" data-copy="SELECT venue, CASE WHEN recurring IN (1,'1','true','TRUE') THEN 'Yes' ELSE 'No' END AS recurring_text FROM open_mics;">Copy</button><pre><span class="k">SELECT</span> venue,
       <span class="k">CASE</span> <span class="k">WHEN</span> recurring <span class="k">IN</span> (1,'1','true','TRUE') <span class="k">THEN</span> 'Yes' <span class="k">ELSE</span> 'No' <span class="k">END</span> <span class="k">AS</span> recurring_text
<span class="k">FROM</span> open_mics;</pre></div>
          </details>
          <details>
            <summary><strong>Joins & Aggregates</strong></summary>
            <div class="sql"><pre><span class="k">SELECT</span> state, <span class="k">COUNT</span>(*) AS shows
<span class="k">FROM</span> open_mics
<span class="k">GROUP BY</span> state
<span class="k">ORDER BY</span> shows <span class="k">DESC</span>;</pre></div>
          </details>
          <details>
            <summary><strong>Window Functions (SQLite ≥ 3.25)</strong></summary>
            <div class="sql"><pre><span class="k">SELECT</span> state, city, venue,
       <span class="k">ROW_NUMBER</span>() <span class="k">OVER</span> (<span class="k">PARTITION BY</span> state <span class="k">ORDER BY</span> city) rn
<span class="k">FROM</span> open_mics;</pre></div>
          </details>
        </section>

        <section id="import-export" class="section">
          <h2>Import / Export</h2>
          <div class="row">
            <div class="shell" style="flex:1"><button class="btn small copy" data-copy="sqlite3 -header -csv open_mics.db \"SELECT state, city, venue, address, day, time, recurring, description FROM open_mics;\" > openmics.csv">Copy</button><pre>$ sqlite3 <span class="k">-header -csv</span> open_mics.db \
"<span class="k">SELECT</span> state, city, venue, address, day, time, recurring, description <span class="k">FROM</span> open_mics;" 
&gt; openmics.csv</pre></div>
            <div class="shell" style="flex:1"><button class="btn small copy" data-copy="sqlite3 my.db \".mode csv\" \".import data.csv open_mics\"">Copy</button><pre>$ sqlite3 my.db 
sqlite&gt; <span class="k">.mode</span> csv
sqlite&gt; <span class="k">.import</span> data.csv open_mics</pre></div>
          </div>
          <details>
            <summary><strong>TSV & Pretty Table</strong></summary>
            <div class="shell"><button class="btn small copy" data-copy="sqlite3 -header -separator $'\t' open_mics.db \"SELECT * FROM open_mics LIMIT 20;\" > sample.tsv">Copy</button><pre>$ sqlite3 -header -separator $'\t' open_mics.db \
"SELECT * FROM open_mics LIMIT 20;" &gt; sample.tsv</pre></div>
          </details>
        </section>

        <section id="schema" class="section">
          <h2>Schema & Migrations</h2>
          <div class="sql"><pre><span class="k">CREATE TABLE</span> open_mics (
  id <span class="k">INTEGER</span> <span class="k">PRIMARY KEY</span>,
  source <span class="k">TEXT</span> <span class="k">NOT NULL</span>,
  state <span class="k">TEXT</span>, city <span class="k">TEXT</span>, venue <span class="k">TEXT</span>,
  address <span class="k">TEXT</span>, day <span class="k">TEXT</span>, time <span class="k">TEXT</span>,
  recurring <span class="k">BOOLEAN</span> <span class="k">DEFAULT</span> 1,
  url <span class="k">TEXT</span>, description <span class="k">TEXT</span>,
  last_updated <span class="k">TIMESTAMP</span> <span class="k">DEFAULT</span> <span class="k">CURRENT_TIMESTAMP</span>
);
</pre></div>
          <details>
            <summary><strong>Alter Table</strong></summary>
            <div class="sql"><pre><span class="k">ALTER TABLE</span> open_mics <span class="k">ADD COLUMN</span> notes <span class="k">TEXT</span>;</pre></div>
          </details>
          <details>
            <summary><strong>Views & CTEs</strong></summary>
            <div class="sql"><pre><span class="k">CREATE VIEW</span> v_export <span class="k">AS</span>
<span class="k">SELECT</span> state, city, venue, address, day, time,
       <span class="k">CASE</span> <span class="k">WHEN</span> recurring <span class="k">IN</span> (1,'1','true','TRUE') <span class="k">THEN</span> 'Yes' <span class="k">ELSE</span> 'No' <span class="k">END</span> <span class="k">AS</span> recurring,
       description
<span class="k">FROM</span> open_mics;

<span class="k">WITH</span> ca <span class="k">AS</span> (
  <span class="k">SELECT</span> * <span class="k">FROM</span> open_mics <span class="k">WHERE</span> state='CA'
)
<span class="k">SELECT</span> city, <span class="k">COUNT</span>(*) <span class="k">FROM</span> ca <span class="k">GROUP BY</span> city;</pre></div>
          </details>
        </section>

        <section id="indexes" class="section">
          <h2>Indexes & Performance</h2>
          <div class="sql"><pre><span class="k">CREATE INDEX</span> idx_open_mics_state_city <span class="k">ON</span> open_mics(state, city);
<span class="k">ANALYZE</span>;
<span class="k">EXPLAIN QUERY PLAN</span> <span class="k">SELECT</span> * <span class="k">FROM</span> open_mics <span class="k">WHERE</span> state='CA' <span class="k">AND</span> city='San Diego';</pre></div>
          <details>
            <summary><strong>Vacuum & Stats</strong></summary>
            <div class="shell"><pre>sqlite&gt; <span class="k">VACUUM</span>;      -- defragment db (can shrink file)
sqlite&gt; <span class="k">ANALYZE</span>;     -- update statistics for planner
sqlite&gt; <span class="k">PRAGMA</span> optimize; -- lightweight maintenance</pre></div>
          </details>
        </section>

        <section id="fts-json" class="section">
          <h2>FTS5 (Full‑Text) & JSON1</h2>
          <details open>
            <summary><strong>FTS5 quickstart</strong></summary>
            <div class="sql"><pre><span class="k">CREATE VIRTUAL TABLE</span> mic_search <span class="k">USING</span> fts5(venue, address, description, content=<span class="v">'open_mics'</span>, content_rowid=<span class="v">'id'</span>);
<span class="k">INSERT INTO</span> mic_search(mic_search) <span class="k">VALUES</span>('rebuild');
<span class="k">SELECT</span> rowid, highlight(mic_search,0,'&lt;mark&gt;','&lt;/mark&gt;') <span class="k">AS</span> venue
<span class="k">FROM</span> mic_search <span class="k">WHERE</span> mic_search <span class="k">MATCH</span> 'coffee NEAR/3 open';</pre></div>
          </details>
          <details>
            <summary><strong>JSON1 examples</strong></summary>
            <div class="sql"><pre><span class="k">SELECT</span> json_extract('{"a":1,"b":[10,20]}', '$.b[1]');  -- 20
<span class="k">SELECT</span> json_set('{"a":1}', '$.b', 2);             -- {"a":1,"b":2}</pre></div>
          </details>
        </section>

        <section id="tx" class="section">
          <h2>Transactions</h2>
          <div class="sql"><pre><span class="k">BEGIN</span> <span class="k">IMMEDIATE</span>;
<span class="k">UPDATE</span> open_mics <span class="k">SET</span> time='8:00pm' <span class="k">WHERE</span> id=1;
<span class="k">COMMIT</span>;  <span class="pill tag">use <span class="hl">ROLLBACK</span> to revert</span></pre></div>
        </section>

        <section id="explain" class="section">
          <h2>Explain / Analyze</h2>
          <div class="shell"><pre>sqlite&gt; <span class="k">EXPLAIN QUERY PLAN</span> <span class="k">SELECT</span> * <span class="k">FROM</span> open_mics <span class="k">WHERE</span> state='CA';
-- look for <span class="hl">SEARCH TABLE</span> using index vs <span class="hl">SCAN</span> (full scan)</pre></div>
        </section>

        <section id="security" class="section">
          <h2>Backups & Safety</h2>
          <div class="shell"><button class="btn small copy" data-copy="sqlite3 open_mics.db \
\".backup backup/open_mics_$(date +%F).db\"">Copy</button><pre>$ mkdir -p backup
$ sqlite3 open_mics.db \
".backup backup/open_mics_$(date +%F).db"</pre></div>
          <ul>
            <li>Always backup before <code>ALTER TABLE</code> or bulk <code>UPDATE</code>.</li>
            <li>Prefer <span class="hl">transactions</span> for multi‑step changes.</li>
            <li>Use <code>PRAGMA foreign_keys = ON;</code> when using FKs.</li>
          </ul>
        </section>

        <section id="one-liners" class="section">
          <h2>Battle‑tested One‑Liners</h2>
          <div class="tablewrap">
            <table class="table">
              <thead><tr><th>Task</th><th>One‑liner</th></tr></thead>
              <tbody>
                <tr><td>List tables</td><td><code>sqlite3 db.db ".tables"</code></td></tr>
                <tr><td>Show columns</td><td><code>sqlite3 db.db "PRAGMA table_info(open_mics);"</code></td></tr>
                <tr><td>CSV export (selected cols)</td><td><code>sqlite3 -header -csv db.db "SELECT state,city,venue,address,day,time,recurring,description FROM open_mics;" &gt; out.csv</code></td></tr>
                <tr><td>TSV preview</td><td><code>sqlite3 -header -separator $'\t' db.db "SELECT * FROM open_mics LIMIT 20;"</code></td></tr>
                <tr><td>Top states</td><td><code>sqlite3 db.db "SELECT state,COUNT(*) c FROM open_mics GROUP BY state ORDER BY c DESC LIMIT 10;"</code></td></tr>
                <tr><td>Check db path</td><td><code>sqlite3 db.db "PRAGMA database_list;"</code></td></tr>
              </tbody>
            </table>
          </div>
        </section>

        <section id="builder" class="section">
          <h2>Interactive Builder: Craft your sqlite3 CSV export</h2>
          <div class="builder">
            <div class="card">
              <div class="row">
                <div style="flex:1">
                  <label>Database file</label>
                  <input type="text" id="db" value="open_mics.db" />
                </div>
                <div style="flex:1">
                  <label>Table</label>
                  <input type="text" id="table" value="open_mics" />
                </div>
              </div>
              <label style="margin-top:8px;display:block">Columns (comma‑separated)</label>
              <input type="text" id="cols" value="state, city, venue, address, day, time, recurring, description" />
              <label style="margin-top:8px;display:block">WHERE (optional)</label>
              <input type="text" id="where" placeholder="state='CA' AND day IN ('sunday','monday')" />
              <div class="row" style="margin-top:8px">
                <div style="flex:1">
                  <label>ORDER BY</label>
                  <input type="text" id="orderby" placeholder="city, venue" />
                </div>
                <div style="flex:1">
                  <label>LIMIT</label>
                  <input type="text" id="limit" placeholder="100" />
                </div>
              </div>
              <div class="row" style="margin-top:10px">
                <button class="btn" id="build">Build Command</button>
                <span class="pill">Output file: <span class="hl">export.csv</span></span>
              </div>
            </div>
            <div class="card">
              <label>Generated command</label>
              <div class="shell cmdout" id="cmdout">Fill the form and click <em>Build Command</em>.</div>
              <div class="row" style="margin-top:8px">
                <button class="btn" id="copycmd">Copy to clipboard</button>
              </div>
            </div>
          </div>
        </section>

        <div class="footer">© Your SQLite3 cheat sheet. Zero external dependencies. Dark‑theme friendly.</div>
      </main>
    </div>
  </div>

<script>
// Copy buttons for code blocks
for (const btn of document.querySelectorAll('.copy')){
  btn.addEventListener('click',()=>{
    const text = btn.getAttribute('data-copy');
    if(text){navigator.clipboard.writeText(text)}
  });
}

// Builder logic
function buildCmd(){
  const db = document.getElementById('db').value.trim() || 'my.db';
  const table = document.getElementById('table').value.trim() || 'my_table';
  const cols = (document.getElementById('cols').value.trim()||'*').replace(/\s*,\s*/g, ', ');
  const where = document.getElementById('where').value.trim();
  const orderby = document.getElementById('orderby').value.trim();
  const limit = document.getElementById('limit').value.trim();

  let sql = `SELECT ${cols} FROM ${table}`;
  if(where) sql += ` WHERE ${where}`;
  if(orderby) sql += ` ORDER BY ${orderby}`;
  if(limit) sql += ` LIMIT ${limit}`;
  sql += ';';

  // Escape double quotes inside SQL when placed in shell string
  const quoted = sql.replaceAll('"', '\\"');
  const cmd = `sqlite3 -header -csv ${db} "${quoted}" > export.csv`;
  document.getElementById('cmdout').textContent = '$ ' + cmd;
  return cmd;
}

(document.getElementById('build')).addEventListener('click', buildCmd);
(document.getElementById('copycmd')).addEventListener('click', ()=>{
  const cmd = buildCmd();
  navigator.clipboard.writeText(cmd);
});
</script>
</body>
</html>