← All studies · askamerica.ai

Minimum wage hikes leave food-service employment essentially unchanged two years later, in a border-county comparison

BLS QCEW county employment (NAICS 722, private), DOL state minimum-wage history, Census county adjacency, 2016-2022 events

Minimum Wage Increases and Food-Service Employment: Border-County E… BLS QCEW county employment, NAICS 722 (food services), private sector; DOL state minimum-wage history; Census county adjacency. 2016-2022 events, 2-year post window. Formal diff-in-diff estimate (log employment) -0.0041 p = 0.97 (not significant) Border-county pairs analyzed 1,203 pairs 23 treated states, 2016-2022 2-year food-service employment growth 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 Side of state line % growth Treated county (state raised min wage >=$0.75/hr) Control county (bordering, no comparable increase) Average over 1,203 border-county pairs; difference not statistically distinguishable from zero (raw gap -0.52pp, formal DiD -0.41pp in log… Dose-response: does a bigger raise predict a bigger effect? 0.0 0.1 0.2 0.3 0.4 0.5 Coefficient (pp per $1) Effect of +$1/hr increase on 2-yr relative growth Coefficient 0.0049 (p=0.39) -- no detectable dose-response; larger raises are not associated with worse relative employment outcomes. Design follows Dube-Lester-Reich / Cengiz-Dube-Lester-Zipperer border-discontinuity logic: adjacent cross-state county pairs share a local labor market and regional shocks but differ in state minimum-wage law. Leave-one-state-out sensitivity: no significance flip across any of the 23 states. AskAmerica · askamerica.ai
SVG

Summary

Using a border-county comparison — the design the minimum-wage literature treats as most credible, because it compares a county to the neighboring county it shares a labor market with, differing only in which state's minimum-wage law applies — a state minimum-wage increase of at least $0.75/hour is not associated with a measurable change in food-service (restaurant/bar) employment over the following two years. Employment in the treated-side counties grew 2.90% on average over the two years after the raise; employment in the bordering, non-raising counties grew 3.42%. A formal difference-in-differences regression (log employment on treatment, post, and their interaction, n=4,812 county-period observations across 1,203 pairs) puts the estimated effect at -0.0041 log points — about -0.4%, statistically indistinguishable from zero (p=0.97). Bigger raises did not produce bigger relative losses either (dose-response coefficient +0.0049 percentage points per additional $1/hr, p=0.39), and the null result is not being carried by any single state (leave-one-state-out testing never flips significance). This matches the dominant strand of the modern minimum-wage literature (Cengiz, Dube, Lester & Zipperer 2019), though it does not settle the older dispute with Neumark & Wascher's panel-data work, which finds small negative effects concentrated in teen and young-adult employment using a different design.

What the literature says first

Before running any original analysis, the published record on this exact question is genuinely split by methodology, and both sides need to be named:

Method — border-county pairs, the credible-identification design

This analysis extends the border-comparison tradition (Dube, Lester & Reich 2010; the identification strategy underlying Cengiz et al.) directly on this warehouse's data, at the industry actually most exposed to a binding minimum wage: food services (NAICS 722), the U.S. industry with the highest concentration of near-minimum-wage jobs.

  1. Identify minimum-wage increase events. From DOL's state minimum-wage history (fiscal.state_minimum_wage_history), computed the year-over-year change in each state's minimum wage, 2016-2022, and kept events with an increase of at least $0.75/hour — large enough to be a meaningful policy shock, not an inflation-indexed nickel-and-dime adjustment.
  2. Build the border-county pair sample. Joined the Census Bureau's county adjacency file (geo.county_adjacency) to find every pair of counties straddling a state line.
  3. Restrict to genuine treatment/control pairs. Kept only pairs where the bordering state did NOT raise its own minimum wage by a comparable amount (control-side increase <$0.25/hr or no change) in that same year — so the pair differs sharply in policy exposure while sharing a local economy. This step yielded 1,834 candidate county-pair events.
  4. Measure the outcome. Pulled food-service (NAICS 722, private-sector) county employment (BLS QCEW, econ.county_qcew) at the event year and again two years later, on both sides of each pair, and computed each side's percent employment growth.
  5. Compare. Averaged the treated-minus-control growth gap across all qualifying pairs, tested it against zero with a formal difference-in-differences regression, and separately regressed the gap on the size of the raise to check for a dose-response relationship.

What was excluded and why: of the 1,834 candidate county-pair events, the query applied the filters b1.annual_avg_emplvl IS NOT NULL, a1.annual_avg_emplvl IS NOT NULL, b2.annual_avg_emplvl IS NOT NULL, and a2.annual_avg_emplvl IS NOT NULL (requiring a non-suppressed BLS employment figure for the treated county at baseline and post, and for the control county at baseline and post). This dropped 631 events (34%), leaving 1,203 pairs with usable employment figures on both sides in both periods. An additional filter, state_fips IS NOT NULL, was applied upstream when building the minimum-wage-change table to exclude the small number of DOL rows for federal/territory jurisdictions (Guam, Puerto Rico, U.S. Virgin Islands, and the federal FLSA row) that carry no state FIPS code and therefore cannot be matched to a state for the border-pair design — this removed 4 non-state jurisdiction rows per year from the pool of candidate "treated" jurisdictions, not from the county-pair sample itself. The employment-suppression exclusion (631 dropped pairs) is driven by BLS's own small-county disclosure rules (protecting the identity of a dominant single employer, disclosure_code='N'), not by anything related to the minimum-wage policy itself, so it is unlikely to bias the direction of the result, but it does skew the surviving 1,203-pair sample slightly toward larger counties with more establishments, where a single employer's suppression is less likely to blank out the whole cell. Re-running the headline comparison is not possible on the excluded 631 pairs because, by definition, they lack a usable employment figure in at least one of the four required cells.

Result

Treated-side 2-yr food-service employment growth (avg)+2.90%
Control-side (bordering, non-raising) 2-yr growth (avg)+3.42%
Raw diff-in-diff (average of pairwise growth gaps)-0.52 percentage points (t=-1.21, p=0.225)
Formal diff-in-diff regression (log employment, treatment x post)-0.0041 log points, i.e. about -0.4% (std. error 0.105, p=0.969)
Dose-response: coefficient on raise size ($/hr)+0.0049 pp per $1 (p=0.39)
Control-side (bordering, non-raising) 2-yr growth (avg)+3.42%
Dose-response: coefficient on raise size ($/hr)+0.0049 pp per $1 (p=0.39)
Formal diff-in-diff regression (log employment, treatment x post)-0.0041 log points, i.e. about -0.4% (std. error 0.105, p=0.969)
Raw diff-in-diff (average of pairwise growth gaps)-0.52 percentage points (t=-1.21, p=0.225)
Treated-side 2-yr food-service employment growth (avg)+2.90%
Dose-response: coefficient on raise size ($/hr)+0.0049 pp per $1 (p=0.39)
Treated-side 2-yr food-service employment growth (avg)+2.90%
Control-side (bordering, non-raising) 2-yr growth (avg)+3.42%
Formal diff-in-diff regression (log employment, treatment x post)-0.0041 log points, i.e. about -0.4% (std. error 0.105, p=0.969)
Raw diff-in-diff (average of pairwise growth gaps)-0.52 percentage points (t=-1.21, p=0.225)

Neither estimate clears conventional statistical significance. The employment gap is small in magnitude (about half a percentage point on a base of roughly 8.4 million food-service jobs in the treated counties) and runs in the direction of slightly slower — not faster — growth on the treated side, but not reliably so; the formal regression estimate is even closer to zero than the simple average-of-gaps figure. There is also no evidence that bigger minimum-wage increases produce worse relative outcomes: the dose-response slope is essentially flat and, if anything, points the wrong way for a disemployment story.

Robustness: leave-one-state-out sensitivity testing (refitting the dose-response regression with each of the 23 treated states removed in turn) never flips the coefficient to statistical significance in either direction — the null result is not an artifact of any single large state (e.g., California, Washington, Virginia, or Minnesota individually).

Caveats and what this does and doesn't show

Every query behind this report

13 warehouse calls ran in this session, in order. Each is reproducible against the same snapshot.

query — 20 rows — 7376 ms
SELECT year, jurisdiction_name, state_fips, wage_amount, value_type, increased_from_prior_column
FROM fiscal.state_minimum_wage_history
WHERE jurisdiction_type='STATE' AND "year" BETWEEN 2015 AND 2023
ORDER BY jurisdiction_name, "year"
FETCH FIRST 20 ROWS ONLY
query — 16792 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2023
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2025 AND state_fips <> neighbor_state_fips
),
neighbor_mw AS (
  SELECT state_fips, "year" AS event_year, diff AS neighbor_diff
  FROM mw
)
SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
       p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
       nm.neighbor_diff AS control_increase
FROM treated t
JOIN pairs p ON p.state_fips = t.state_fips
LEFT JOIN neighbor_mw nm ON nm.state_fips = p.neighbor_state_fips AND nm.event_year = t.event_year
WHERE (nm.neighbor_diff IS NULL OR nm.neighbor_diff < 0.25)
FETCH FIRST 10 ROWS ONLY
query — 20 rows — 7922 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
)
SELECT state_fips, "year", wage_amount, diff FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2023 ORDER BY diff DESC FETCH FIRST 20 ROWS ONLY
query — 1 rows — 903 ms
SELECT COUNT(*) FROM geo.county_adjacency WHERE "year"=2025 AND state_fips <> neighbor_state_fips
query — 11 rows — 2463 ms
SELECT "year", COUNT(*) FROM geo.county_adjacency WHERE state_fips <> neighbor_state_fips GROUP BY "year" ORDER BY "year"
query — 10 rows — 20709 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2023
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2024 AND state_fips <> neighbor_state_fips
)
SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
       p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
       nm.diff AS control_increase
FROM treated t
JOIN pairs p ON p.state_fips = t.state_fips
LEFT JOIN mw nm ON nm.state_fips = p.neighbor_state_fips AND nm."year" = t.event_year
WHERE (nm.diff IS NULL OR nm.diff < 0.25)
FETCH FIRST 10 ROWS ONLY
query — 500 rows — 55903 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2022
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2024 AND state_fips <> neighbor_state_fips
),
events AS (
  SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
         p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
         nm.diff AS control_increase
  FROM treated t
  JOIN pairs p ON p.state_fips = t.state_fips
  LEFT JOIN mw nm ON nm.state_fips = p.neighbor_state_fips AND nm."year" = t.event_year
  WHERE (nm.diff IS NULL OR nm.diff < 0.25)
),
emp_t0 AS (
  SELECT area_fips, "year", annual_avg_emplvl FROM econ.county_qcew
  WHERE industry_code='722' AND own_code='5'
),
joined AS (
  SELECT e.*, 
    b1.annual_avg_emplvl AS treated_emp_base, a1.annual_avg_emplvl AS treated_emp_post,
    b2.annual_avg_emplvl AS control_emp_base, a2.annual_avg_emplvl AS control_emp_post
  FROM events e
  JOIN emp_t0 b1 ON b1.area_fips = e.treated_county AND b1."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a1 ON a1.area_fips = e.treated_county AND a1."year" = CAST(e.event_year + 2 AS VARCHAR)
  JOIN emp_t0 b2 ON b2.area_fips = e.control_county AND b2."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a2 ON a2.area_fips = e.control_county AND a2."year" = CAST(e.event_year + 2 AS VARCHAR)
  WHERE b1.annual_avg_emplvl IS NOT NULL AND a1.annual_avg_emplvl IS NOT NULL
    AND b2.annual_avg_emplvl IS NOT NULL AND a2.annual_avg_emplvl IS NOT NULL
    AND b1.annual_avg_emplvl > 0 AND b2.annual_avg_emplvl > 0
)
SELECT treated_state, event_year, treated_increase, treated_county, control_county, control_state,
  treated_emp_base, treated_emp_post, control_emp_base, control_emp_post,
  (treated_emp_post - treated_emp_base)*1.0/treated_emp_base AS treated_growth,
  (control_emp_post - control_emp_base)*1.0/control_emp_base AS control_growth
FROM joined
ORDER BY treated_state, event_year
query — 1 rows — 56812 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2022
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2024 AND state_fips <> neighbor_state_fips
),
events AS (
  SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
         p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
         nm.diff AS control_increase
  FROM treated t
  JOIN pairs p ON p.state_fips = t.state_fips
  LEFT JOIN mw nm ON nm.state_fips = p.neighbor_state_fips AND nm."year" = t.event_year
  WHERE (nm.diff IS NULL OR nm.diff < 0.25)
),
emp_t0 AS (
  SELECT area_fips, "year", annual_avg_emplvl FROM econ.county_qcew
  WHERE industry_code='722' AND own_code='5'
),
joined AS (
  SELECT e.*, 
    b1.annual_avg_emplvl AS treated_emp_base, a1.annual_avg_emplvl AS treated_emp_post,
    b2.annual_avg_emplvl AS control_emp_base, a2.annual_avg_emplvl AS control_emp_post
  FROM events e
  JOIN emp_t0 b1 ON b1.area_fips = e.treated_county AND b1."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a1 ON a1.area_fips = e.treated_county AND a1."year" = CAST(e.event_year + 2 AS VARCHAR)
  JOIN emp_t0 b2 ON b2.area_fips = e.control_county AND b2."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a2 ON a2.area_fips = e.control_county AND a2."year" = CAST(e.event_year + 2 AS VARCHAR)
  WHERE b1.annual_avg_emplvl IS NOT NULL AND a1.annual_avg_emplvl IS NOT NULL
    AND b2.annual_avg_emplvl IS NOT NULL AND a2.annual_avg_emplvl IS NOT NULL
    AND b1.annual_avg_emplvl > 0 AND b2.annual_avg_emplvl > 0
),
growth AS (
  SELECT *,
    (treated_emp_post - treated_emp_base)*1.0/treated_emp_base AS treated_growth,
    (control_emp_post - control_emp_base)*1.0/control_emp_base AS control_growth
  FROM joined
)
SELECT COUNT(*) AS n_pairs,
  COUNT(DISTINCT treated_state) AS n_states,
  AVG(treated_growth) AS avg_treated_growth,
  AVG(control_growth) AS avg_control_growth,
  AVG(treated_growth - control_growth) AS avg_diff_in_diff,
  STDDEV_SAMP(treated_growth - control_growth) AS sd_did,
  SUM(treated_emp_base) AS total_treated_base_emp,
  SUM(treated_emp_post) AS total_treated_post_emp,
  SUM(control_emp_base) AS total_control_base_emp,
  SUM(control_emp_post) AS total_control_post_emp
FROM growth
hypothesis_test — 59813 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2022
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2024 AND state_fips <> neighbor_state_fips
),
events AS (
  SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
         p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
         nm.diff AS control_increase
  FROM treated t
  JOIN pairs p ON p.state_fips = t.state_fips
  LEFT JOIN mw nm ON nm.state_fips = p.neighbor_state_fips AND nm."year" = t.event_year
  WHERE (nm.diff IS NULL OR nm.diff < 0.25)
),
emp_t0 AS (
  SELECT area_fips, "year", annual_avg_emplvl FROM econ.county_qcew
  WHERE industry_code='722' AND own_code='5'
),
joined AS (
  SELECT e.*, 
    b1.annual_avg_emplvl AS treated_emp_base, a1.annual_avg_emplvl AS treated_emp_post,
    b2.annual_avg_emplvl AS control_emp_base, a2.annual_avg_emplvl AS control_emp_post
  FROM events e
  JOIN emp_t0 b1 ON b1.area_fips = e.treated_county AND b1."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a1 ON a1.area_fips = e.treated_county AND a1."year" = CAST(e.event_year + 2 AS VARCHAR)
  JOIN emp_t0 b2 ON b2.area_fips = e.control_county AND b2."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a2 ON a2.area_fips = e.control_county AND a2."year" = CAST(e.event_year + 2 AS VARCHAR)
  WHERE b1.annual_avg_emplvl IS NOT NULL AND a1.annual_avg_emplvl IS NOT NULL
    AND b2.annual_avg_emplvl IS NOT NULL AND a2.annual_avg_emplvl IS NOT NULL
    AND b1.annual_avg_emplvl > 0 AND b2.annual_avg_emplvl > 0
)
SELECT treated_state,
  (treated_emp_post - treated_emp_base)*1.0/treated_emp_base - (control_emp_post - control_emp_base)*1.0/control_emp_base AS did
FROM joined
ols_regression — 68216 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2022
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2024 AND state_fips <> neighbor_state_fips
),
events AS (
  SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
         p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
         nm.diff AS control_increase
  FROM treated t
  JOIN pairs p ON p.state_fips = t.state_fips
  LEFT JOIN mw nm ON nm.state_fips = p.neighbor_state_fips AND nm."year" = t.event_year
  WHERE (nm.diff IS NULL OR nm.diff < 0.25)
),
emp_t0 AS (
  SELECT area_fips, "year", annual_avg_emplvl FROM econ.county_qcew
  WHERE industry_code='722' AND own_code='5'
),
joined AS (
  SELECT e.*, 
    b1.annual_avg_emplvl AS treated_emp_base, a1.annual_avg_emplvl AS treated_emp_post,
    b2.annual_avg_emplvl AS control_emp_base, a2.annual_avg_emplvl AS control_emp_post
  FROM events e
  JOIN emp_t0 b1 ON b1.area_fips = e.treated_county AND b1."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a1 ON a1.area_fips = e.treated_county AND a1."year" = CAST(e.event_year + 2 AS VARCHAR)
  JOIN emp_t0 b2 ON b2.area_fips = e.control_county AND b2."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a2 ON a2.area_fips = e.control_county AND a2."year" = CAST(e.event_year + 2 AS VARCHAR)
  WHERE b1.annual_avg_emplvl IS NOT NULL AND a1.annual_avg_emplvl IS NOT NULL
    AND b2.annual_avg_emplvl IS NOT NULL AND a2.annual_avg_emplvl IS NOT NULL
    AND b1.annual_avg_emplvl > 0 AND b2.annual_avg_emplvl > 0
)
SELECT treated_state, treated_increase,
  (treated_emp_post - treated_emp_base)*1.0/treated_emp_base - (control_emp_post - control_emp_base)*1.0/control_emp_base AS did
FROM joined
sensitivity_analysis — 74958 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2022
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2024 AND state_fips <> neighbor_state_fips
),
events AS (
  SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
         p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
         nm.diff AS control_increase
  FROM treated t
  JOIN pairs p ON p.state_fips = t.state_fips
  LEFT JOIN mw nm ON nm.state_fips = p.neighbor_state_fips AND nm."year" = t.event_year
  WHERE (nm.diff IS NULL OR nm.diff < 0.25)
),
emp_t0 AS (
  SELECT area_fips, "year", annual_avg_emplvl FROM econ.county_qcew
  WHERE industry_code='722' AND own_code='5'
),
joined AS (
  SELECT e.*, 
    b1.annual_avg_emplvl AS treated_emp_base, a1.annual_avg_emplvl AS treated_emp_post,
    b2.annual_avg_emplvl AS control_emp_base, a2.annual_avg_emplvl AS control_emp_post
  FROM events e
  JOIN emp_t0 b1 ON b1.area_fips = e.treated_county AND b1."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a1 ON a1.area_fips = e.treated_county AND a1."year" = CAST(e.event_year + 2 AS VARCHAR)
  JOIN emp_t0 b2 ON b2.area_fips = e.control_county AND b2."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a2 ON a2.area_fips = e.control_county AND a2."year" = CAST(e.event_year + 2 AS VARCHAR)
  WHERE b1.annual_avg_emplvl IS NOT NULL AND a1.annual_avg_emplvl IS NOT NULL
    AND b2.annual_avg_emplvl IS NOT NULL AND a2.annual_avg_emplvl IS NOT NULL
    AND b1.annual_avg_emplvl > 0 AND b2.annual_avg_emplvl > 0
)
SELECT treated_state, treated_increase,
  (treated_emp_post - treated_emp_base)*1.0/treated_emp_base - (control_emp_post - control_emp_base)*1.0/control_emp_base AS did
FROM joined
query — 1 rows — 39718 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2022
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2024 AND state_fips <> neighbor_state_fips
),
events AS (
  SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
         p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
         nm.diff AS control_increase
  FROM treated t
  JOIN pairs p ON p.state_fips = t.state_fips
  LEFT JOIN mw nm ON nm.state_fips = p.neighbor_state_fips AND nm."year" = t.event_year
  WHERE (nm.diff IS NULL OR nm.diff < 0.25)
)
SELECT COUNT(*) AS candidate_pairs FROM events
diff_in_diff — 318461 ms
WITH mw AS (
  SELECT state_fips, "year", wage_amount,
         wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff
  FROM fiscal.state_minimum_wage_history
  WHERE jurisdiction_type='STATE' AND value_type='SINGLE' AND state_fips IS NOT NULL
),
treated AS (
  SELECT state_fips, "year" AS event_year, diff
  FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2022
),
pairs AS (
  SELECT DISTINCT county_fips, state_fips, neighbor_county_fips, neighbor_state_fips
  FROM geo.county_adjacency
  WHERE "year" = 2024 AND state_fips <> neighbor_state_fips
),
events AS (
  SELECT t.state_fips AS treated_state, t.event_year, t.diff AS treated_increase,
         p.county_fips AS treated_county, p.neighbor_county_fips AS control_county, p.neighbor_state_fips AS control_state,
         nm.diff AS control_increase
  FROM treated t
  JOIN pairs p ON p.state_fips = t.state_fips
  LEFT JOIN mw nm ON nm.state_fips = p.neighbor_state_fips AND nm."year" = t.event_year
  WHERE (nm.diff IS NULL OR nm.diff < 0.25)
),
emp_t0 AS (
  SELECT area_fips, "year", annual_avg_emplvl FROM econ.county_qcew
  WHERE industry_code='722' AND own_code='5'
),
joined AS (
  SELECT e.treated_county, e.control_county, e.event_year,
    b1.annual_avg_emplvl AS treated_emp_base, a1.annual_avg_emplvl AS treated_emp_post,
    b2.annual_avg_emplvl AS control_emp_base, a2.annual_avg_emplvl AS control_emp_post
  FROM events e
  JOIN emp_t0 b1 ON b1.area_fips = e.treated_county AND b1."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a1 ON a1.area_fips = e.treated_county AND a1."year" = CAST(e.event_year + 2 AS VARCHAR)
  JOIN emp_t0 b2 ON b2.area_fips = e.control_county AND b2."year" = CAST(e.event_year AS VARCHAR)
  JOIN emp_t0 a2 ON a2.area_fips = e.control_county AND a2."year" = CAST(e.event_year + 2 AS VARCHAR)
  WHERE b1.annual_avg_emplvl IS NOT NULL AND a1.annual_avg_emplvl IS NOT NULL
    AND b2.annual_avg_emplvl IS NOT NULL AND a2.annual_avg_emplvl IS NOT NULL
    AND b1.annual_avg_emplvl > 0 AND b2.annual_avg_emplvl > 0
),
panel AS (
  SELECT treated_county AS unit, event_year, 1 AS treatment, 0 AS post, LN(treated_emp_base) AS log_emp FROM joined
  UNION ALL
  SELECT treated_county, event_year, 1, 1, LN(treated_emp_post) FROM joined
  UNION ALL
  SELECT control_county, event_year, 0, 0, LN(control_emp_base) FROM joined
  UNION ALL
  SELECT control_county, event_year, 0, 1, LN(control_emp_post) FROM joined
)
SELECT * FROM panel

Sources

  1. DOL state minimum-wage history (fiscal.state_minimum_wage_history) — Queried via AskAmerica connector
    Show SQL
    WITH mw AS (SELECT state_fips, "year", wage_amount, wage_amount - LAG(wage_amount) OVER (PARTITION BY state_fips ORDER BY "year") AS diff FROM fiscal.state_minimum_wage_history WHERE jurisdiction_type='STATE' AND value_type='SINGLE') SELECT * FROM mw WHERE diff >= 0.75 AND "year" BETWEEN 2016 AND 2022
  2. BLS QCEW county employment, NAICS 722 private (econ.county_qcew) — Queried via AskAmerica connector, diff-in-diff computation shown in report text
    Show SQL
    SELECT area_fips, "year", annual_avg_emplvl FROM econ.county_qcew WHERE industry_code='722' AND own_code='5'
  3. Census Bureau county adjacency file (geo.county_adjacency) — Used to build border-county pair sample frame, year=2024 vintage (evergreen file)
  4. Formal difference-in-differences regression
    Show tool call
    diff_in_diff(outcome="log_emp", treatment="treatment", post="post")
  5. Cengiz, Dube, Lester & Zipperer, "The Effect of Minimum Wages on Low-Wage Jobs," NBER Working Paper 25434 / QJE 2019
  6. Neumark, Salas & Wascher, "Revisiting the Minimum Wage-Employment Debate," NBER Working Paper 18681
  7. Upjohn Institute, "Research on the Effects of Raising the Minimum Wage"