O*NET-SOC vs BLS SOC Codes: How the Two Datasets Connect
By Rovaryn Digital · May 19, 2026 · 9 min read

You spotted a decimal point difference — and it actually matters
You're looking up electricians in two government databases at the same time. In the BLS OEWS wage tables the code reads 47-2111. Over on O*NET OnLine the same trade shows up as 47-2111.00. Same electrician, different notation — and if you're trying to pull wage data and job-profile data into the same spreadsheet or offer template, that tiny difference is exactly where the join breaks.
This isn't a typo. It's a deliberate design choice by two federal agencies that built their systems for different purposes and different audiences. Once you understand the logic, you can connect the two datasets cleanly — and when you do, you get something neither database gives you on its own: the wage percentiles and the full occupational profile in a single view.
This article explains the structure of each coding system, where they overlap, where they diverge, and the practical steps for joining them so you can build an offer around real data instead of gut feel.
What a SOC code actually is (and why both systems use one)
SOC stands for Standard Occupational Classification — a six-digit numbering system maintained by the U.S. Office of Management and Budget (OMB) that the federal government uses to count, measure, and compare workers across agencies. The structure is hierarchical:
- First two digits = major group (e.g., 47 = Construction and Extraction)
- Digits three and four = minor group (e.g., 47-2 = Construction Trades Workers)
- Digits five and six = detailed occupation (e.g., 47-2111 = Electricians)
The BLS uses this six-digit SOC code as the primary key in the Occupational Employment and Wage Statistics (OEWS) survey — the same survey that produces every wage figure you see on the Occupational Outlook Handbook. When the BLS reports that electricians earned a national median of $62,350/yr in May 2024 (BLS, May 2024, national), that figure is attached to SOC 47-2111. For a deeper look at how SOC codes work across the trades, see our guide to what a SOC code means for trade employers.
O*NET — the Occupational Information Network, developed by the U.S. Department of Labor's Employment and Training Administration — also organizes its database around SOC codes. But it extends them.
The O*NET-SOC system: what the decimal adds
ONET appends a two-digit suffix after a decimal point to create *ONET-SOC codes* in the format XX-XXXX.XX. For most trades, the suffix is .00, which means the ONET occupation maps one-to-one with the BLS SOC detailed occupation. So 47-2111.00 (Electricians) in ONET is simply the full O*NET-SOC representation of BLS SOC 47-2111.
The decimal system exists because O*NET needs more granularity than the SOC standard provides in some places. There are two scenarios:
1. One-to-one (suffix .00). The BLS SOC detailed code maps to exactly one O*NET occupation. Most trade codes fall here. Electricians, HVAC mechanics, carpenters, welders, sheet metal workers — all .00. The join is trivial: strip the decimal and suffix, match the six-digit code.
2. One-to-many (suffixes .01, .02, …). ONET splits a single BLS SOC code into multiple specialized roles. For example, BLS SOC 47-2152 covers Plumbers, Pipefitters, and Steamfitters as one wage series (they share a single wage row in OEWS — you will never find separate BLS wage figures for plumbers vs. pipefitters, because BLS doesn't publish them separately). ONET, however, can list 47-2152.01 Pipe Fitters and Steamfitters and 47-2152.02 Plumbers as distinct occupational profiles, each with its own task list and skill ratings. The job descriptions differ; the wage data does not.
This split is where employers most often get confused: they see two ONET profiles and expect two wage rows from BLS. There's only one. For wage purposes, roll both ONET sub-codes back up to the six-digit parent and use the single OEWS estimate.
The ONET system currently covers more than 1,000 occupation titles organized around these codes, with over 19,000 task statements across the database. That depth — skills, abilities, knowledge domains, work activities, work context, and Job Zone ratings — is what makes the ONET side of the join valuable for something beyond wage-setting. Learn more about what that profile contains in our overview of O*NET occupational profiles for trades.
What each dataset contributes to an offer decision
Knowing the coding structure is only useful if you know what each side of the join actually gives you. Here's a plain-English breakdown:
BLS OEWS (the wage side)
- Employment estimates by occupation and geography (national, state, metro)
- Mean wage, median wage, and percentile wages (10th, 25th, 50th, 75th, 90th)
- Updated annually on a May reference date; released roughly six months later
- Coverage: approximately 800 detailed occupations across national, state, and ~530 metro areas
- Built from a sample of about 1.1 million establishments (BLS)
What it does not contain: any description of what workers actually do, what skills they need, how long training takes, or how physically demanding the role is.
O*NET (the occupational-profile side)
- Tasks, tools, and technology
- Skills, knowledge, and abilities rated by importance and level
- Work activities and work context (outdoor exposure, physical demands, decision-making pace)
- Job Zone — a 1–5 scale grouping occupations by the education, experience, and training typically required (1 = little preparation needed; 5 = extensive preparation). Job Zone tells you, at a glance, how long it realistically takes to source and onboard a qualified candidate.
- Education and training data
What it does not contain: wage data of any kind.
Neither dataset alone gives you what you need to write an offer. The BLS side tells you the number; the O*NET side tells you what you're paying for and how hard the role is to fill.
How to join them: the practical crosswalk
The join is straightforward once you know the rule.
Step 1: Start with the O*NET-SOC code. Pull the occupation from ONET OnLine (onetonline.org). Note the full ONET-SOC code, e.g., 47-2111.00.
Step 2: Truncate to six digits. Drop the decimal and the two-digit suffix: 47-2111. This is your BLS SOC key.
Step 3: Look up the BLS OEWS estimate. Go to bls.gov/oes, select the SOC code 47-2111, and choose your geography — national for a baseline, then state or metro for a local comparison. The OEWS tables give you the 10th, 25th, 50th, 75th, and 90th percentile wages.
Step 4: Watch for suppressed cells. BLS suppresses estimates that don't meet publication standards or that are based on very small samples — for instance, occupations with estimated employment below a certain threshold in a given area. If a metro cell is suppressed, step up to the state figure; if the state is suppressed, use the national figure and note it. Never infer a local number from a national one.
Step 5: Combine. You now have wage percentiles keyed to the same occupation that has a full ONET profile. The percentile — say, anchoring toward the upper end of the electrician range, between the $62,350 national median and the $106,030 90th percentile (BLS, May 2024, national) — becomes your offer anchor; the ONET profile (Job Zone 3, apprenticeship typically 3–4 years, licensing exam required) becomes the context that explains why you're offering at that level.
For a complete walkthrough of how to turn these percentiles into a min/midpoint/max salary band, see our skilled trades wage benchmarking guide.
A worked example: electricians, joined
To make this concrete, here's what the join looks like for one trade using figures from the verified-data library.
O*NET-SOC: 47-2111.00 — Electricians
BLS SOC (truncated key): 47-2111
BLS OEWS wage data (May 2024, national):
| Percentile | Annual wage |
|---|---|
| 10th | $39,430 |
| Median (50th) | $62,350 |
| 90th | $106,030 |
(Source: BLS, May 2024, national. For current figures, visit bls.gov/oes.)
O*NET profile highlights (47-2111.00):
- Job Zone: 3 (medium preparation — apprenticeship typically 3–4 years plus licensing)
- Top skills include installation, troubleshooting, and reading technical diagrams
- Work context includes outdoor exposure and safety-critical decision-making
With both sides joined, you can read the 75th-percentile wage as a competitive offer anchor and immediately explain to your hiring manager why you're not anchoring at the 25th: Job Zone 3 with a multi-year apprenticeship and a state license means the candidate pool is structurally smaller than a Job Zone 2 role, and the 9% projected growth rate (BLS, 2024–34, national) means it's shrinking relative to demand.
That's the conversation the crosswalk makes possible. Neither dataset makes it alone.
The two things to remember at the spreadsheet level
Before you build your next offer template:
The truncation rule is your join key. ONET-SOC
.00→ six-digit BLS SOC, one-to-one. ONET-SOC.01/.02→ same six-digit parent, one wage row. Never look for separate BLS wage figures for O*NET sub-codes.The geography is not optional. A national median is not a local rate. Always confirm your metro or state figure in bls.gov/oes before presenting a wage to a candidate. If the cell is suppressed, say so and use the next level up.
If you want to see both datasets pre-joined and surfaced in an employer-ready format — wage percentiles by trade and geography alongside the O*NET profile — take a look at what we've built on the SkilledMarkets features page and our pricing.
Want a short weekly note on using BLS and ONET data to price trade offers? Subscribe to the SkilledMarkets newsletter — no spam, just the data points that matter to your next hire.*
This article includes information from ONET OnLine, developed by the U.S. Department of Labor, Employment and Training Administration. ONET is a registered trademark of the U.S. Department of Labor, Employment and Training Administration.
Ready to go beyond the guide? Benchmark trade wages with live BLS data.
Get free wage guides in your inbox
BLS data explainers and salary band tips for trade contractors.


