Export SQL Results to Google Sheets

Last updated May 19, 2026 · By the SaturnSQL team

Google Sheets is the most common destination for SaturnSQL query results. This guide walks through connecting your Google account, picking a destination tab, choosing append vs replace, setting a refresh cadence, and dealing with the few things that break this workflow in practice.

If you are coming from a tool like SeekWell or PopSQL, the model is similar (and intentionally so): a saved query writes its results into a tab on a real spreadsheet, on a schedule, ready for downstream dashboards.

What you need

  • A saved query in SaturnSQL that runs successfully against your database.
  • A Google account with edit access to the target spreadsheet.
  • The destination spreadsheet itself, with a dedicated tab where results should land.

Step 1: Authenticate your Google account

From a saved query, open the destination panel and pick Google Sheets. SaturnSQL will redirect you to Google's OAuth screen, where you sign in with the account that owns or has edit access to the target spreadsheet. Approve the requested permissions (read and write access to the specific files SaturnSQL writes to).

Tip: Use a shared team Google account for production exports, not a personal one. When a team member leaves, you do not want their personal Google account taking the schedules with them.

Step 2: Pick the destination spreadsheet and tab

Once authenticated, browse to the spreadsheet you want to write to. Pick the specific tab (sheet) within that spreadsheet for the destination. Use a dedicated tab per query instead of overwriting a shared tab, so different queries do not stomp on each other.

A common pattern teams use:

  • One spreadsheet per team (Marketing, Product, Finance)
  • One tab per scheduled query (daily-active-users, monthly-revenue, churn-by-cohort)
  • Downstream pivot tables, charts, and Looker Studio connections live in separate "view" tabs that reference the raw data tabs

Step 3: Choose append vs replace

This is the decision that matters most for downstream consumers:

  • Append — each run adds new rows to the bottom of the existing tab. Headers are written on the first run only. Use this for time-series data where you want history (daily signup counts, hourly latency metrics).
  • Replace — each run clears the tab and writes a fresh snapshot, headers and all. Use this for current-state dashboards (today's open tickets, current user count by plan).

Tip: If you are unsure, replace is the safer default. Appending forever can grow into hundreds of thousands of rows and slow the spreadsheet down. If you need history, write the query to include a date column and use replace, snapshotting the full history each run.

Step 4: Set the refresh frequency

Pick how often the export should refresh. The same cadence options apply as anywhere else in SaturnSQL: hourly, daily, weekly, or a custom cron expression. See the scheduling guide for details on each option and timezone handling.

For one-off exports, you can skip the schedule entirely and trigger the export manually whenever you need fresh data.

Step 5: Run a test export

Trigger the export once before enabling the schedule. Open the destination sheet and check:

  • Did the headers land in row 1?
  • Are columns in the order you expect?
  • Did number formatting come through correctly (or do you need to format columns in the sheet)?
  • If downstream dashboards already exist, do they still resolve?

Handling header rows

SaturnSQL writes column names as the header row. In replace mode this means row 1 is rewritten on every run, which is usually fine. In append mode, headers are written only on the first run; new runs add rows without a header.

If your column list might change over time, prefer replace mode. Appending with a changed column list can drift the column positions in old rows.

Troubleshooting

"Permission denied" on an export that used to work

The Google account you connected has lost edit access to the destination spreadsheet. Most common causes: the spreadsheet owner removed sharing; the spreadsheet was moved into a shared drive with different permissions; or the OAuth grant to SaturnSQL was revoked from the user's Google account settings. Reconnect the Google account and reconfirm the destination.

The destination sheet was renamed or deleted

A rename is usually fine because SaturnSQL stores the internal sheet ID, not the display name. A delete (or moving the spreadsheet to trash) causes the next export to fail. Reconnect and pick a new destination.

Numbers are being written as text

Usually a column-formatting issue in the destination tab. Open the tab, select the affected columns, and set the format to Number or Currency. New rows written by SaturnSQL will inherit that format.

Too many rows / sheet is slow

Append mode can grow unbounded. If a sheet has tens or hundreds of thousands of rows and is slow to open, switch to replace mode and add a date column to your SQL, snapshotting only the last 90 days of history.

Related help articles

Ready to sync your SQL to Google Sheets?