No SAS Licence? Open a .sas7bdat File and Turn It into CSV
A .sas7bdat file lands in your inbox: the output of a SAS job, a data set from a statistician, an extract from an analytics server nobody has logged into for years. Without SAS on your machine it is a locked box. You do not need the licence to see inside it — or to turn it into a CSV.
Why It Will Not Just Open
.sas7bdat is SAS’s own binary data set format, and SAS has never published a specification for it. Excel does not know it and a text editor shows noise. Every reader outside SAS is built from years of reverse engineering, which is why the choice of tool matters.
| Approach | What it costs |
|---|---|
| SAS itself | The obvious answer if you have a licence. Most people who are handed a .sas7bdat do not. |
| Python, with pandas or pyreadstat | Works well once Python is installed and set up. On a locked-down work laptop, that is the hard part. |
| R, with haven | The same story: excellent, after an install. |
| An online converter | No install, but the data set goes to somebody else’s server — and SAS data is usually clinical, financial or customer data. |
Doing It in the Browser
OmniSelect FileSQL reads SAS data sets with ReadStat — the open-source library that R’s haven and Python’s pyreadstat are built on — compiled to WebAssembly and served from this site. It runs inside your browser tab; the file is never uploaded.
- Open the app.
- Drop the file onto the File Select panel. A row appears with the type SAS7BDAT and a one-letter table name in the Alias column, taken from the first letter of the file name:
loans.sas7bdatbecomesL. - Look at it.
SELECT * FROM L LIMIT 100
| loan_id | branch | product | amount | rate | opened | status |
|---|---|---|---|---|---|---|
| 5001 | Leeds | Mortgage | 185000 | 4.15 | 2024-03-18 | Current |
| 5002 | Leeds | Personal | 8500 | 9.9 | 2025-01-07 | Current |
| 5003 | Bristol | Auto | 21000 | 6.4 | 2024-11-22 | Arrears |
| 5006 | Glasgow | Personal | 12000 | 10.5 | 2024-06-14 | Closed |
| 5007 | Leeds | Auto | 17500 | 2025-02-26 | Current |
Two things have already been taken care of. opened is stored in the file as a number of days since 1 January 1960 — 23453 for the first row — and SAS shows it through its DATE9. format; here it arrives as a real date, 2024-03-18. And loan 5007’s rate was missing in SAS (a .), so its cell is empty: NULL in SQL, which averages skip rather than count as zero.
Ask It Questions
Type a question into the plain-English box and the SQL is written for you, inside your browser, with no AI service. total amount by branch becomes:
SELECT branch, SUM(amount) AS total_amount FROM L GROUP BY branch
| branch | total_amount |
|---|---|
| Leeds | 410000 |
| Bristol | 265000 |
| Glasgow | 179250 |
average rate by product gives SELECT product, AVG(rate) AS avg_rate FROM L GROUP BY product. Auto comes back as 6.25: the average of the two rates on file, with the missing one left out. loans where status is Arrears gives:
SELECT * FROM L WHERE status = 'Arrears'
Because dates are dates, date conditions work the way you would write them. Loans opened since the start of 2025, by branch:
SELECT branch, COUNT(*) AS loans, SUM(amount) AS principal FROM L WHERE opened >= '2025-01-01' GROUP BY branch ORDER BY principal DESC
| branch | loans | principal |
|---|---|---|
| Bristol | 1 | 238000 |
| Leeds | 2 | 26000 |
| Glasgow | 1 | 24750 |
And WHERE rate IS NULL finds the rows with a missing rate, so you can see exactly what an average left out.
Drop a .sas7bdat file in and see inside it.
Open the app →From .sas7bdat to CSV
- Run
SELECT * FROM Lfor the whole data set, or a narrower query for just the rows and columns you need. - Open the Export menu above the results and choose CSV.
The file is written in your browser and saved straight to your disk:
loan_id,branch,product,amount,rate,opened,status 5001,Leeds,Mortgage,185000,4.15,2024-03-18,Current 5002,Leeds,Personal,8500,9.9,2025-01-07,Current 5003,Bristol,Auto,21000,6.4,2024-11-22,Arrears … 5007,Leeds,Auto,17500,,2025-02-26,Current
Dates are written as YYYY-MM-DD, which every spreadsheet and database reads, and a missing value is an empty field. The export holds every row of the result, not only the 1,000 the Row limit box shows on screen. The same menu writes Excel, JSON and Parquet — Parquet keeps the column types and is compressed, which makes it a good long-term home for a SAS extract.
What Comes Across
| In the SAS data set | In the table |
|---|---|
| Character variables | Text |
| Numeric variables | Numbers |
Date formats: DATE9., MMDDYY10., YYMMDD10., E8601DA. … | Dates, such as 2024-03-18 |
Datetime formats: DATETIME20. … | Date and time, such as 2024-03-18 14:30:00 |
Time formats: TIME8. … | A time of day, such as 14:30:00 |
Missing values (.) | Empty — NULL in SQL |
Compressed data sets (COMPRESS=YES) | Read like any other |
| Variable labels | Not shown: columns are named by the variable names, in lower case |
User-defined formats (PROC FORMAT) | Not applied: you see the stored codes. The formats live in a separate .sas7bcat catalog, which is not read |
A gzipped copy, loans.sas7bdat.gz, opens the same way without being extracted first, and a .zip of several data sets turns each one into its own table — see the .gz guide.
Reasonable Questions
Is it reading the file the way SAS does?
It reads it with ReadStat, the same library R and Python users rely on for SAS files. Values, dates and missing values come through as shown above; what SAS would add from outside the file, such as a format catalog, does not.
How large a data set can it open?
Up to 50 MB and 1,000,000 rows per file. SAS data sets are often stored uncompressed, so 50 MB may be fewer rows than you expect. For larger ones, pyreadstat in Python can read a data set in chunks.
Can I save it back as a .sas7bdat?
No. Exports are CSV, JSON, Excel or Parquet. SAS reads a CSV back with PROC IMPORT.
Does it change my file?
No. The browser hands the page a read-only copy of the file you chose. Nothing is written back and nothing is uploaded — here is how to check.
Can I join it to a spreadsheet or a CSV?
Yes. Every file you add becomes a table, whatever its format, and up to 26 can be joined in one query — see querying 26 files at once.