OmniSelect FileSQL

Guides
← Back to App
Home › Guides › Reading an SPSS .sav file without SPSS

Survey Data Stuck in a .sav File? Read It Without SPSS

.sav is how survey data travels — from panel providers and research agencies, university data archives and national statistics offices. Without an SPSS licence the file is a locked box, and the fieldwork you paid for is inside it. Here is how to open it, tabulate it and hand it on, in a browser tab.

The Usual Routes

ApproachWhat it costs
IBM SPSS StatisticsA licence or subscription, for what may be one look at one file.
PSPPA free program that reads .sav files. An install, which on a managed laptop means a ticket.
R (haven) or Python (pyreadstat)Excellent, for people who write code.
ExcelCannot open a .sav file at all.
An online converterRespondent-level data sent to an unknown server — personal data you would have to account for.

Doing It in the Browser

OmniSelect FileSQL reads SPSS files with ReadStat, the open-source library behind R’s haven and Python’s pyreadstat, compiled to WebAssembly and run inside your browser tab. The file is never uploaded.

  1. Open the app.
  2. Drop the .sav file onto the File Select panel. It gets a row with the type SAV and a one-letter table name in the Alias column: survey.sav becomes S.
  3. Look at it.
    SELECT * FROM S LIMIT 100
resp_idregionregion_labelq1_satisq1_satis_labelrecommendrecommend_labelageint_dateweight
1011North5Very satisfied1Yes342026-03-021.2
1022South4Satisfied1Yes512026-03-020.8
1031North2Dissatisfied0No292026-03-031
1054West3Neutral0No622026-03-040.9
1062South1Yes382026-03-051.3

Every variable with value labels comes in twice: the code as stored, and a _label column beside it with what the code means — q1_satis 5 is Very satisfied. The interview date, held by SPSS as seconds since 1582, is a real date.

Respondent 106 answered 9, Refused, which the file defines as a user-missing value. As in SPSS, it is treated as missing: both cells are empty, and statistics leave it out. Compare a count of rows with a count of scores:

SELECT region_label, COUNT(*) AS answers, COUNT(q1_satis) AS scored,
       ROUND(AVG(q1_satis), 2) AS avg_score
FROM S
GROUP BY region_label
ORDER BY avg_score DESC
region_labelanswersscoredavg_score
West334.33
South324
East333.67
North332.67

South has three respondents but two scores: the refusal did not drag its average towards 9.

Your SPSS Habits, in SQL

In SPSSHere
FREQUENCIESGROUP BY with COUNT(*), and a percentage
CROSSTABSGROUP BY two columns
MEANSAVG by group, as above
SELECT IFWHERE
WEIGHT BYSUM(x * weight) / SUM(weight)

A frequency table, in code order, with percentages:

SELECT q1_satis_label, COUNT(*) AS n,
       ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) AS pct
FROM S
GROUP BY q1_satis, q1_satis_label
ORDER BY q1_satis
q1_satis_labelnpct
Very dissatisfied18.3
Dissatisfied216.7
Neutral18.3
Satisfied325
Very satisfied433.3
18.3

The empty row is the missing answer, listed last as SPSS lists missing values.

A crosstab of region by whether they would recommend:

SELECT region_label, recommend_label, COUNT(*) AS n
FROM S
GROUP BY region_label, recommend_label
ORDER BY region_label, recommend_label

A weighted mean. The weight is just a column, so a weighted average is written out — dividing only by the weights of respondents who have a score:

SELECT region_label,
       ROUND(SUM(q1_satis * weight) / SUM(CASE WHEN q1_satis IS NOT NULL THEN weight END), 2) AS weighted_score
FROM S
GROUP BY region_label
ORDER BY weighted_score DESC
region_labelweighted_score
West4.38
South4
East3.62
North2.81

SELECT IF: respondents aged 40 or over who would not recommend:

SELECT resp_id, region_label, age FROM S WHERE recommend_label = 'No' AND age >= 40

Drop a .sav file in and see inside it.

Open the app →

Or Just Ask

The plain-English box writes the SQL for you, inside your browser, with no AI service. It works from the column names: count by q1_satis_label becomes SELECT q1_satis_label, COUNT(*) AS count_rows FROM S GROUP BY q1_satis_label, and average age by region_label becomes SELECT region_label, AVG(age) AS avg_age FROM S GROUP BY region_label. The SQL is shown beside the question, ready to edit before you run it.

Handing It On

For a colleague without SPSS, run SELECT * FROM S and choose Export › CSV (or Excel). Codes and labels travel side by side:

resp_id,region,region_label,q1_satis,q1_satis_label,recommend,recommend_label,age,int_date,weight
101,1,North,5,Very satisfied,1,Yes,34,2026-03-02,1.2
102,2,South,4,Satisfied,1,Yes,51,2026-03-02,0.8
…
106,2,South,,,1,Yes,38,2026-03-05,1.3

The export holds every row of the result, not only the rows on screen.

What Comes Across

In the SPSS fileIn the table
Numeric and string variablesNumbers and text
Value labelsThe code, plus a <name>_label column holding its label
Date formats: DATE, ADATE, EDATE, SDATE …Dates, such as 2026-03-02
DATETIMEDate and time
TIMEA time, such as 14:30:00
System-missing and user-missing valuesEmpty — NULL in SQL
Variable labels (the question wording)Not shown: columns are named by the variable names, so keep the questionnaire to hand
.zsav (compressed) and .por (portable) filesRead the same way

Reasonable Questions

Is it reading the file correctly?

It uses ReadStat, the library R and Python users rely on for SPSS files. Codes, labels, dates and missing values come through as shown above.

How large a file can it open?

Up to 50 MB and 1,000,000 rows per file. For larger files, keep only the variables you need in PSPP, R or Python first.

Can I save a .sav file?

No. Exports are CSV, JSON, Excel or Parquet.

Is respondent data uploaded?

No. The file is read inside your browser, and after the page has loaded it makes no network requests — check it in about a minute. For work under a data-sharing agreement, see working with client data under an NDA.

Related Guides