Guide
How to export SQL query results to CSV automatically
Automate a recurring SQL to CSV export on SQL Server, PostgreSQL, MySQL, Azure SQL and Redshift: native options, where each breaks, what is simpler.
Guide
Automate a recurring SQL to CSV export on SQL Server, PostgreSQL, MySQL, Azure SQL and Redshift: native options, where each breaks, what is simpler.
Exporting a query result to CSV once is a right click in any SQL client. Doing it every morning at seven, without anyone opening the client, is a different problem, and the forum threads asking how to do it go back fifteen years because every database answers it differently.
Every automated export has the same four parts: something that runs on a schedule, something that executes the query, something that writes a correct CSV, and something that delivers the file to a person. Databases are good at the second part and uneven at the other three.
| Database | Scheduler inside the database | Writes a file | Sends it |
|---|---|---|---|
| SQL Server (Standard, Enterprise) | SQL Server Agent | sp_send_dbmail attachment, bcp, SSIS |
Database Mail |
| SQL Server Express | none | sqlcmd, bcp from outside |
none |
| Azure SQL Database | Elastic Jobs | none | none |
| PostgreSQL | pg_cron extension | COPY on the server, \copy from psql |
none |
| MySQL | Event Scheduler | SELECT ... INTO OUTFILE on the server |
none |
| Amazon Redshift | Query Editor v2 schedules | UNLOAD to S3 |
none |
The table explains why almost every working solution ends up outside the database: a scheduler on another machine, a client that runs the query and writes the file there, and a mail relay or chat webhook to deliver it.
The traps are specific enough that each engine has its own guide:
Invoke-Sqlcmd with Export-Csv, and why Send-MailMessage fails against Microsoft 365.COPY versus \copy, why pg_cron alone produces nothing a person can open, and what changes on RDS and Cloud SQL.secure_file_priv, the missing header row in INTO OUTFILE, and the client-side alternative.Quoting. A CSV is only correct if values with commas, quotes and line breaks are quoted. COPY ... WITH (FORMAT csv), PowerShell Export-Csv and MySQL Shell get it right. Database Mail attachments, sqlcmd output and mysql --batch do not, and the file looks fine until the first customer name with a comma in it.
Encoding. Excel opens a UTF-8 CSV correctly only when the file starts with a byte order mark or the user imports it explicitly. Accented names turning into pairs of odd characters is the most common complaint about automated exports.
Credentials. Every script needs a database login and usually a mail password. Both end up in a file on a server, readable by whoever has access to that server.
Silence. When the job fails, the evidence is in a local log, a job history or a mail queue. The person waiting for the file notices first, usually days later.
The homemade setup is the right call for one export owned by the engineer who wrote it. It stops being the right call when the exports are owned by people who think in SQL rather than in cron syntax, when there are several databases of different kinds, or when someone asks which reports went out this week and nobody can answer.
Taavik's scheduled exports cover the four parts in one place. An agent inside the network runs the query against PostgreSQL, MySQL, SQL Server, Azure SQL or Redshift and only connects outbound. The file is a quoted CSV with a header and a byte order mark, or an Excel file with a frozen header row. Schedules run daily, weekly, monthly, on an interval or on cron with the Pro plan, each in its own time zone. Delivery goes to an email list or a Slack channel, optionally only when rows came back, and each run leaves a record with its status and row count.
One difference from a script is intentional. The file is encrypted on the agent before upload, and recipients open it through a link with a passphrase instead of finding an attachment. For an extract with personal data that is the point. For a recipient who wants the spreadsheet in the inbox it is one extra click, and worth mentioning before switching.
The free plan includes one connection and one daily schedule, which is enough to retire the first script and decide about the rest.