If you have ever joined to FIRST_REF_VALUES and watched the row count multiply, or pulled the wrong description for a code, you have met the one rule that governs this table: its codes are not unique on their own. FIRST_REF_VALUES is where the cryptic reference codes scattered through the NEC schema get their readable names, and reading it correctly is the difference between a report that ties out and one that quietly does not.
What the table actually is
NEC Housing, formerly Northgate, stores most of its descriptive values not as readable text but as short codes, with the human-readable name held in FIRST_REF_VALUES. Ownership type, job location, trade, tenure, variation reason, void class: each is a code on the source row that you join to FRV_CODE, reading FRV_NAME for the label.
Why the domain filter is not optional
The catch is that FIRST_REF_VALUES codes are not unique across domains. The same short code can mean one thing under OWN_TYPE and something entirely different under LOCATION. The fix is to always pin the join with FRV_FRD_DOMAIN. Leave it off and you either multiply rows, one per domain that happens to share the code, or pull a description from the wrong domain.
SELECT pro.pro_refno,
frv.frv_name AS ownership_type
FROM properties pro
JOIN first_ref_values frv
ON frv.frv_code = pro.pro_hou_hrv_hot_code
AND frv.frv_frd_domain = 'OWN_TYPE'A trap worth knowing: the column prefix does not always name the domain. Property ownership lives in PRO_HOU_HRV_HOT_CODE, prefixed HOT, but the domain you filter on is OWN_TYPE, not HOT. Trust the domain, never the prefix.
FIRST_REF_VALUES is not STATUS_CODES
This is the one that catches people. Workflow status, a works order moving through new, authorised, completed and cancelled, does not live in FIRST_REF_VALUES at all. It lives in STATUS_CODES, joined on SCO_CODE together with SCO_OBJECT_CODE, because those codes are scoped per entity. FIRST_REF_VALUES is for descriptive reference data; STATUS_CODES is for lifecycle state. Reach for the wrong one and the join simply will not resolve.
These codes are not complicated, just undocumented. Decode them once, pinned to the right domain, and a whole class of reporting disagreement disappears.