← All studies · askamerica.ai

Only 29% of Companies' 10-K Climate Risk Disclosures Name Their Own State's Most Common Disaster Type

Item 1A risk-factor text for 3,665 FY2024 10-K filers vs. FEMA disaster declarations at HQ state, 2015-2024

SEC Climate Risk Disclosures Rarely Match Companies' Actual Disaster His… 3,665 2024 10-K filers, Item 1A risk factors vs. FEMA disaster declarations 2015-2024 at HQ state Companies naming their state's #1 FEMA hazard 29% 71% do not name it Corr: state disaster load vs. mentioning "climate change" r = 0.03 essentially no relationship Match rate: company names its state's dominant FEMA hazard type 0 10 20 30 40 50 Dominant hazard in HQ state % of companies Flood states Hurricane states Wildfire states Tornado/severe-storm states Winter-storm states n=3,665 companies; hazard = most frequent FEMA declaration type in company's HQ state, 2015-2024 "Earthquake" risk-factor mentions look like boilerplate, not location risk 0 10 20 30 40 50 60 Company's HQ-state dominant hazard (not earthquake) % mentioning earthquake Flood states Tornado/severe-storm states Hurricane states Winter-storm states Wildfire states Earthquake mention rate is HIGHEST among wildfire-state companies, not earthquake-prone ones — consistent with generic legal boilerplate AskAmerica · askamerica.ai
SVG

Summary

Not well. Comparing the Item 1A (Risk Factors) text of 3,665 companies' FY2024 10-K filings against FEMA disaster-declaration history for their headquarters state (2015-2024), only 29% of companies mention the specific disaster type that is actually their state's most frequently declared FEMA hazard — 71% do not name it anywhere in their risk factors. Match rates vary sharply by hazard: companies in flood-dominant states name "flood" 41% of the time and hurricane-state companies name "hurricane" 37% of the time, but wildfire-state companies name "wildfire" only 24% of the time, tornado/severe-storm-state companies name that hazard 20% of the time, and winter-storm-state companies name it only 7% of the time. Separately, 45% of companies mention "climate change" generically somewhere in their risk factors, but how often they do so is essentially uncorrelated with how disaster-prone their home state actually is (r=0.03 against total FEMA declarations 2015-2024). A third check reinforces the boilerplate interpretation: "earthquake" is mentioned by 28-55% of companies regardless of whether their state has any meaningful earthquake history — mentioned MOST often (54.5%) by companies headquartered in wildfire-dominant states, not seismically active ones. Together these point to climate/disaster risk language in 10-Ks functioning largely as generic legal boilerplate rather than a location-tailored account of the disaster history a company's own operations actually face.

Method

Disclosure side: sec.risk_factor_sections (Item 1A text) for all FY2024 10-K filings, searched for company-level presence (ILIKE, case-insensitive, any paragraph) of hazard-specific terms: hurricane/tropical storm, flood, wildfire, tornado/severe storm, winter storm/snowstorm/severe ice storm, earthquake, and the phrase "climate change."

Location side: each company's headquarters state was extracted from sec.filing_metadata.mailing_address (regex match on the trailing ", ST ZIP" pattern) for its most recent 2024 10-K. This is the registrant's mailing address, not a full inventory of every facility/plant/store the company operates — a real limitation discussed below.

Actual disaster history: disasters.disaster_declarations (FEMA), 2015-2024, restricted to weather/geologic incident types. Two categories of FEMA declaration rows were deliberately excluded from the state "dominant hazard" calculation and are called out here by name rather than silently dropped: (1) declarations coded "Biological" (7,857 of 32,853 declaration-county rows nationally over 2015-2024, the single largest incident-type category — overwhelmingly COVID-19 declarations, not a physical climate hazard; including them would have made "Biological" the dominant declared hazard for nearly every state, answering a different, non-climate question), and (2) a residual bucket of miscellaneous incident types — "Other," "Toxic Substances," and "Volcanic Eruption" (16 + 1 + 2 = 19 rows nationally, under 0.1% of all rows) — that were grouped into a catch-all "other" category and excluded from the six named hazard buckets because each individually affects only one or two states and is too small to be any state's meaningful "dominant" hazard. Dropping this "other" bucket changes no state's dominant-hazard assignment: every state's top category by count is one of the six named hazards (hurricane, flood, wildfire, tornado/severe storm, winter storm, earthquake) with or without these 19 residual rows included.

Sample construction and exclusions. Of 5,560 distinct companies filing a 10-K in 2024, 691 (12.4%) carry no mailing_address in filing_metadata and were dropped — these are disproportionately asset-backed securitization trusts and shell/blank-check entities that file with the SEC but have no genuine operating address, so their omission does not distort the operating-company comparison this report is about. A further roughly 1,200 companies were dropped because their address's state abbreviation did not resolve to a US state (foreign private issuers headquartered outside the US, e.g. Canada, Israel, UK) or because no matching 2024 Item 1A risk-factor section was found for that filing. The final analysis sample is 3,665 companies, all US-headquartered operating companies with both a resolvable HQ state and Item 1A text.

Match test: for each company, checked whether its risk-factor keyword flag for its state's dominant hazard was positive (e.g., a Texas company, where hurricane is the state's dominant declared hazard, was checked for the word "hurricane"/"tropical storm" anywhere in its Item 1A text).

Findings in detail

Flood54640.7%
Hurricane1,38137.3%
Wildfire93024.0%
Tornado / severe storm38520.0%
Winter storm4237.3%
Flood54640.7%
Hurricane1,38137.3%
Tornado / severe storm38520.0%
Wildfire93024.0%
Winter storm4237.3%
Hurricane1,38137.3%
Wildfire93024.0%
Flood54640.7%
Winter storm4237.3%
Tornado / severe storm38520.0%
Flood54640.7%
Hurricane1,38137.3%
Wildfire93024.0%
Tornado / severe storm38520.0%
Winter storm4237.3%

Overall keyword prevalence across all 3,665 companies regardless of their own state's hazard mix: flood 45.3%, earthquake 40.3%, hurricane 33.8%, "climate change" 45.1%, tornado/severe storm 21.4%, wildfire 18.4%, winter storm 3.8%. Flood and earthquake are mentioned so broadly that they read as standard risk-factor boilerplate across almost all industries and locations, not evidence of location-specific risk assessment — flood is named about as often by companies in non-flood-dominant states as flood-dominant ones, and earthquake mention rates by hazard-category (28-55%) show no relationship to actual seismic exposure at all.

Winter storms are the sharpest gap: despite being the single most frequently FEMA-declared hazard for 423 companies' home states (largely Texas, after 2021's Winter Storm Uri, and several Mid-Atlantic/Midwest states), only 7.3% of those companies mention "winter storm," "snowstorm," or "ice storm" as a risk factor — suggesting winter weather is treated as an operational nuisance rather than a disclosed material risk, even where it has generated the state's most federal disaster activity.

Caveats

What This Report Does Not Answer

Every query behind this report

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

query — 714 ms
SELECT cik, company_name, business_address FROM sec.filing_metadata WHERE filing_type='10-K' AND business_address IS NOT NULL LIMIT 10
query — 10 rows — 978 ms
SELECT cik, company_name, business_address, mailing_address FROM sec.filing_metadata WHERE filing_type='10-K' LIMIT 10
query — 1 rows — 23 ms
SELECT REGEXP_REPLACE('123 MAIN ST, IRVINE, CA 92614', '.*,\s*([A-Z]{2})\s+[0-9]{5}$', '$1') AS x
query — 1 rows — 22 ms
SELECT REGEXP_REPLACE('123 MAIN ST, IRVINE, CA 92614', '.*, ([A-Z]{2}) [0-9]{5}$', '\1') AS x
query — 791 ms

WITH parsed AS (
  SELECT cik, company_name, mailing_address,
    REGEXP_REPLACE(mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr
  FROM sec.filing_metadata
  WHERE filing_type='10-K' AND mailing_address IS NOT NULL
)
SELECT state_abbr, count(DISTINCT cik) AS n_companies FROM parsed WHERE LENGTH(state_abbr)=2 GROUP BY state_abbr ORDER BY 2 DESC LIMIT 15
query — 20 rows — 880 ms
SELECT mailing_address, REGEXP_REPLACE(mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr
FROM sec.filing_metadata WHERE filing_type='10-K' AND mailing_address IS NOT NULL LIMIT 20
query — 863 ms

WITH parsed AS (
  SELECT DISTINCT cik, company_name,
    REGEXP_REPLACE(mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr
  FROM sec.filing_metadata
  WHERE filing_type='10-K' AND mailing_address IS NOT NULL
)
SELECT state_abbr, count(*) AS n_companies FROM parsed WHERE LENGTH(state_abbr)=2 GROUP BY state_abbr ORDER BY 2 DESC LIMIT 15
query — 822 ms

WITH parsed AS (
  SELECT cik,
    REGEXP_REPLACE(mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr
  FROM sec.filing_metadata
  WHERE filing_type='10-K' AND mailing_address IS NOT NULL
)
SELECT state_abbr, count(*) AS n FROM parsed WHERE LENGTH(state_abbr)=2 GROUP BY state_abbr ORDER BY n DESC LIMIT 15
query — 20 rows — 1416 ms

SELECT REGEXP_REPLACE(mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr, count(*) AS n
FROM sec.filing_metadata
WHERE filing_type='10-K' AND mailing_address IS NOT NULL
GROUP BY REGEXP_REPLACE(mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1')
ORDER BY n DESC LIMIT 20
query — 5 rows — 2852 ms
SELECT state_abbr, state_fips, state_name FROM geo.state_ref LIMIT 5
query — 8 rows — 11660 ms

SELECT year, count(DISTINCT cik) AS n_ciks, count(*) AS n_filings
FROM sec.filing_metadata WHERE filing_type='10-K'
GROUP BY year ORDER BY year
query — 19 rows — 12606 ms

SELECT incident_type, count(*) AS n
FROM disasters.disaster_declarations
WHERE "year" BETWEEN 2015 AND 2024
GROUP BY incident_type ORDER BY n DESC
query — 51 rows — 2751 ms

WITH company_state AS (
  SELECT fm.cik, fm.accession_number, fm.company_name,
    REGEXP_REPLACE(fm.mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr,
    ROW_NUMBER() OVER (PARTITION BY fm.cik ORDER BY fm.filing_date DESC) AS rn
  FROM sec.filing_metadata fm
  WHERE fm.filing_type='10-K' AND fm."year"=2024 AND fm.mailing_address IS NOT NULL
)
SELECT cs.state_abbr, sr.state_fips, count(DISTINCT cs.cik) AS n_companies
FROM company_state cs
JOIN geo.state_ref sr ON sr.state_abbr = cs.state_abbr
WHERE cs.rn = 1
GROUP BY cs.state_abbr, sr.state_fips
ORDER BY n_companies DESC
query — 1 rows — 1798 ms

SELECT count(*) FROM sec.risk_factor_sections WHERE "year"=2024
query — 224 rows — 18638 ms

SELECT state_fips, incident_type, count(*) AS n
FROM disasters.disaster_declarations
WHERE CAST("year" AS INTEGER) BETWEEN 2015 AND 2024
  AND incident_type IN ('Hurricane','Severe Storm','Flood','Severe Ice Storm','Tropical Storm','Fire','Snowstorm','Tornado','Coastal Storm','Earthquake','Winter Storm','Mud/Landslide','Typhoon','Dam/Levee Break','Straight-Line Winds')
GROUP BY state_fips, incident_type
query — 1 rows — 30448 ms

WITH flags AS (
  SELECT cik, accession_number,
    MAX(CASE WHEN paragraph_text ILIKE '%hurricane%' OR paragraph_text ILIKE '%tropical storm%' THEN 1 ELSE 0 END) AS m_hurricane,
    MAX(CASE WHEN paragraph_text ILIKE '%flood%' THEN 1 ELSE 0 END) AS m_flood,
    MAX(CASE WHEN paragraph_text ILIKE '%wildfire%' THEN 1 ELSE 0 END) AS m_wildfire,
    MAX(CASE WHEN paragraph_text ILIKE '%tornado%' THEN 1 ELSE 0 END) AS m_tornado,
    MAX(CASE WHEN paragraph_text ILIKE '%winter storm%' OR paragraph_text ILIKE '%severe ice storm%' OR paragraph_text ILIKE '%snowstorm%' THEN 1 ELSE 0 END) AS m_winter,
    MAX(CASE WHEN paragraph_text ILIKE '%earthquake%' THEN 1 ELSE 0 END) AS m_earthquake,
    MAX(CASE WHEN paragraph_text ILIKE '%drought%' THEN 1 ELSE 0 END) AS m_drought,
    MAX(CASE WHEN paragraph_text ILIKE '%climate change%' THEN 1 ELSE 0 END) AS m_climate,
    MAX(CASE WHEN paragraph_text ILIKE '%severe weather%' OR paragraph_text ILIKE '%extreme weather%' THEN 1 ELSE 0 END) AS m_severe_weather
  FROM sec.risk_factor_sections
  WHERE "year"=2024
  GROUP BY cik, accession_number
)
SELECT count(*) AS n_filings,
  SUM(m_hurricane) AS n_hurricane, SUM(m_flood) AS n_flood, SUM(m_wildfire) AS n_wildfire,
  SUM(m_tornado) AS n_tornado, SUM(m_winter) AS n_winter, SUM(m_earthquake) AS n_earthquake,
  SUM(m_drought) AS n_drought, SUM(m_climate) AS n_climate, SUM(m_severe_weather) AS n_severe_weather
FROM flags
query — 56 rows — 18927 ms

WITH state_hazard AS (
  SELECT state_fips,
    CASE
      WHEN incident_type IN ('Hurricane','Tropical Storm','Coastal Storm','Typhoon') THEN 'hurricane'
      WHEN incident_type IN ('Flood','Dam/Levee Break') THEN 'flood'
      WHEN incident_type = 'Fire' THEN 'wildfire'
      WHEN incident_type IN ('Tornado','Severe Storm','Straight-Line Winds') THEN 'tornado_severe'
      WHEN incident_type IN ('Winter Storm','Snowstorm','Severe Ice Storm') THEN 'winter'
      WHEN incident_type = 'Earthquake' THEN 'earthquake'
      WHEN incident_type = 'Mud/Landslide' THEN 'mudslide'
      ELSE 'other'
    END AS hazard_cat,
    count(*) AS n
  FROM disasters.disaster_declarations
  WHERE CAST("year" AS INTEGER) BETWEEN 2015 AND 2024
  GROUP BY state_fips,
    CASE
      WHEN incident_type IN ('Hurricane','Tropical Storm','Coastal Storm','Typhoon') THEN 'hurricane'
      WHEN incident_type IN ('Flood','Dam/Levee Break') THEN 'flood'
      WHEN incident_type = 'Fire' THEN 'wildfire'
      WHEN incident_type IN ('Tornado','Severe Storm','Straight-Line Winds') THEN 'tornado_severe'
      WHEN incident_type IN ('Winter Storm','Snowstorm','Severe Ice Storm') THEN 'winter'
      WHEN incident_type = 'Earthquake' THEN 'earthquake'
      WHEN incident_type = 'Mud/Landslide' THEN 'mudslide'
      ELSE 'other'
    END
),
dominant AS (
  SELECT state_fips, hazard_cat, n,
    ROW_NUMBER() OVER (PARTITION BY state_fips ORDER BY n DESC) AS rk
  FROM state_hazard
  WHERE hazard_cat <> 'other'
)
SELECT state_fips, hazard_cat AS dominant_hazard, n AS declaration_count
FROM dominant WHERE rk=1
ORDER BY state_fips
query — 1 rows — 52156 ms

WITH company_state AS (
  SELECT fm.cik, fm.accession_number,
    REGEXP_REPLACE(fm.mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr,
    ROW_NUMBER() OVER (PARTITION BY fm.cik ORDER BY fm.filing_date DESC) AS rn
  FROM sec.filing_metadata fm
  WHERE fm.filing_type='10-K' AND fm."year"=2024 AND fm.mailing_address IS NOT NULL
),
cs1 AS (SELECT cik, accession_number, state_abbr FROM company_state WHERE rn=1),
flags AS (
  SELECT cik, accession_number,
    MAX(CASE WHEN paragraph_text ILIKE '%hurricane%' OR paragraph_text ILIKE '%tropical storm%' THEN 1 ELSE 0 END) AS m_hurricane,
    MAX(CASE WHEN paragraph_text ILIKE '%flood%' THEN 1 ELSE 0 END) AS m_flood,
    MAX(CASE WHEN paragraph_text ILIKE '%wildfire%' THEN 1 ELSE 0 END) AS m_wildfire,
    MAX(CASE WHEN paragraph_text ILIKE '%tornado%' OR paragraph_text ILIKE '%severe storm%' THEN 1 ELSE 0 END) AS m_tornado,
    MAX(CASE WHEN paragraph_text ILIKE '%winter storm%' OR paragraph_text ILIKE '%severe ice storm%' OR paragraph_text ILIKE '%snowstorm%' THEN 1 ELSE 0 END) AS m_winter,
    MAX(CASE WHEN paragraph_text ILIKE '%earthquake%' THEN 1 ELSE 0 END) AS m_earthquake,
    MAX(CASE WHEN paragraph_text ILIKE '%climate change%' THEN 1 ELSE 0 END) AS m_climate
  FROM sec.risk_factor_sections
  WHERE "year"=2024
  GROUP BY cik, accession_number
),
state_hazard AS (
  SELECT state_fips,
    CASE
      WHEN incident_type IN ('Hurricane','Tropical Storm','Coastal Storm','Typhoon') THEN 'hurricane'
      WHEN incident_type IN ('Flood','Dam/Levee Break') THEN 'flood'
      WHEN incident_type = 'Fire' THEN 'wildfire'
      WHEN incident_type IN ('Tornado','Severe Storm','Straight-Line Winds') THEN 'tornado_severe'
      WHEN incident_type IN ('Winter Storm','Snowstorm','Severe Ice Storm') THEN 'winter'
      WHEN incident_type = 'Earthquake' THEN 'earthquake'
      WHEN incident_type = 'Mud/Landslide' THEN 'mudslide'
      ELSE 'other'
    END AS hazard_cat,
    count(*) AS n
  FROM disasters.disaster_declarations
  WHERE CAST("year" AS INTEGER) BETWEEN 2015 AND 2024
  GROUP BY state_fips,
    CASE
      WHEN incident_type IN ('Hurricane','Tropical Storm','Coastal Storm','Typhoon') THEN 'hurricane'
      WHEN incident_type IN ('Flood','Dam/Levee Break') THEN 'flood'
      WHEN incident_type = 'Fire' THEN 'wildfire'
      WHEN incident_type IN ('Tornado','Severe Storm','Straight-Line Winds') THEN 'tornado_severe'
      WHEN incident_type IN ('Winter Storm','Snowstorm','Severe Ice Storm') THEN 'winter'
      WHEN incident_type = 'Earthquake' THEN 'earthquake'
      WHEN incident_type = 'Mud/Landslide' THEN 'mudslide'
      ELSE 'other'
    END
),
dominant AS (
  SELECT state_fips, hazard_cat, n,
    ROW_NUMBER() OVER (PARTITION BY state_fips ORDER BY n DESC) AS rk
  FROM state_hazard WHERE hazard_cat <> 'other'
),
dom1 AS (SELECT state_fips, hazard_cat AS dominant_hazard, n AS dom_count FROM dominant WHERE rk=1),
state_totals AS (
  SELECT state_fips, SUM(n) AS total_declarations FROM state_hazard WHERE hazard_cat <> 'other' GROUP BY state_fips
),
joined AS (
  SELECT cs.cik, cs.state_abbr, sr.state_fips, dm.dominant_hazard, dm.dom_count, st.total_declarations,
    f.m_hurricane, f.m_flood, f.m_wildfire, f.m_tornado, f.m_winter, f.m_earthquake, f.m_climate,
    CASE dm.dominant_hazard
      WHEN 'hurricane' THEN f.m_hurricane
      WHEN 'flood' THEN f.m_flood
      WHEN 'wildfire' THEN f.m_wildfire
      WHEN 'tornado_severe' THEN f.m_tornado
      WHEN 'winter' THEN f.m_winter
      WHEN 'earthquake' THEN f.m_earthquake
      ELSE NULL
    END AS matched_dominant
  FROM cs1 cs
  JOIN geo.state_ref sr ON sr.state_abbr = cs.state_abbr
  JOIN flags f ON f.cik = cs.cik AND f.accession_number = cs.accession_number
  LEFT JOIN dom1 dm ON dm.state_fips = sr.state_fips
  LEFT JOIN state_totals st ON st.state_fips = sr.state_fips
)
SELECT count(*) AS n_companies,
  AVG(matched_dominant) AS match_rate_dominant_hazard,
  AVG(m_climate) AS pct_mention_climate_change,
  AVG(m_hurricane) AS pct_hurricane, AVG(m_flood) AS pct_flood, AVG(m_wildfire) AS pct_wildfire,
  AVG(m_tornado) AS pct_tornado_severe, AVG(m_winter) AS pct_winter, AVG(m_earthquake) AS pct_earthquake,
  corr(total_declarations, m_climate) AS corr_disasters_vs_climate_mention
FROM joined
query — 1 rows — 52583 ms

WITH company_state AS (
  SELECT fm.cik, fm.accession_number,
    REGEXP_REPLACE(fm.mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr,
    ROW_NUMBER() OVER (PARTITION BY fm.cik ORDER BY fm.filing_date DESC) AS rn
  FROM sec.filing_metadata fm
  WHERE fm.filing_type='10-K' AND fm."year"=2024 AND fm.mailing_address IS NOT NULL
),
cs1 AS (SELECT cik, accession_number, state_abbr FROM company_state WHERE rn=1),
flags AS (
  SELECT cik, accession_number,
    MAX(CASE WHEN paragraph_text ILIKE '%hurricane%' OR paragraph_text ILIKE '%tropical storm%' THEN 1 ELSE 0 END) AS m_hurricane,
    MAX(CASE WHEN paragraph_text ILIKE '%flood%' THEN 1 ELSE 0 END) AS m_flood,
    MAX(CASE WHEN paragraph_text ILIKE '%wildfire%' THEN 1 ELSE 0 END) AS m_wildfire,
    MAX(CASE WHEN paragraph_text ILIKE '%tornado%' OR paragraph_text ILIKE '%severe storm%' THEN 1 ELSE 0 END) AS m_tornado,
    MAX(CASE WHEN paragraph_text ILIKE '%winter storm%' OR paragraph_text ILIKE '%severe ice storm%' OR paragraph_text ILIKE '%snowstorm%' THEN 1 ELSE 0 END) AS m_winter,
    MAX(CASE WHEN paragraph_text ILIKE '%earthquake%' THEN 1 ELSE 0 END) AS m_earthquake,
    MAX(CASE WHEN paragraph_text ILIKE '%climate change%' THEN 1 ELSE 0 END) AS m_climate
  FROM sec.risk_factor_sections
  WHERE "year"=2024
  GROUP BY cik, accession_number
),
state_hazard AS (
  SELECT state_fips,
    CASE
      WHEN incident_type IN ('Hurricane','Tropical Storm','Coastal Storm','Typhoon') THEN 'hurricane'
      WHEN incident_type IN ('Flood','Dam/Levee Break') THEN 'flood'
      WHEN incident_type = 'Fire' THEN 'wildfire'
      WHEN incident_type IN ('Tornado','Severe Storm','Straight-Line Winds') THEN 'tornado_severe'
      WHEN incident_type IN ('Winter Storm','Snowstorm','Severe Ice Storm') THEN 'winter'
      WHEN incident_type = 'Earthquake' THEN 'earthquake'
      WHEN incident_type = 'Mud/Landslide' THEN 'mudslide'
      ELSE 'other'
    END AS hazard_cat,
    count(*) AS n
  FROM disasters.disaster_declarations
  WHERE CAST("year" AS INTEGER) BETWEEN 2015 AND 2024
  GROUP BY state_fips,
    CASE
      WHEN incident_type IN ('Hurricane','Tropical Storm','Coastal Storm','Typhoon') THEN 'hurricane'
      WHEN incident_type IN ('Flood','Dam/Levee Break') THEN 'flood'
      WHEN incident_type = 'Fire' THEN 'wildfire'
      WHEN incident_type IN ('Tornado','Severe Storm','Straight-Line Winds') THEN 'tornado_severe'
      WHEN incident_type IN ('Winter Storm','Snowstorm','Severe Ice Storm') THEN 'winter'
      WHEN incident_type = 'Earthquake' THEN 'earthquake'
      WHEN incident_type = 'Mud/Landslide' THEN 'mudslide'
      ELSE 'other'
    END
),
dominant AS (
  SELECT state_fips, hazard_cat, n,
    ROW_NUMBER() OVER (PARTITION BY state_fips ORDER BY n DESC) AS rk
  FROM state_hazard WHERE hazard_cat <> 'other'
),
dom1 AS (SELECT state_fips, hazard_cat AS dominant_hazard, n AS dom_count FROM dominant WHERE rk=1),
state_totals AS (
  SELECT state_fips, SUM(n) AS total_declarations FROM state_hazard WHERE hazard_cat <> 'other' GROUP BY state_fips
),
joined AS (
  SELECT cs.cik, cs.state_abbr, sr.state_fips, dm.dominant_hazard, dm.dom_count, st.total_declarations,
    CAST(f.m_hurricane AS DOUBLE) AS m_hurricane, CAST(f.m_flood AS DOUBLE) AS m_flood,
    CAST(f.m_wildfire AS DOUBLE) AS m_wildfire, CAST(f.m_tornado AS DOUBLE) AS m_tornado,
    CAST(f.m_winter AS DOUBLE) AS m_winter, CAST(f.m_earthquake AS DOUBLE) AS m_earthquake,
    CAST(f.m_climate AS DOUBLE) AS m_climate,
    CAST(CASE dm.dominant_hazard
      WHEN 'hurricane' THEN f.m_hurricane
      WHEN 'flood' THEN f.m_flood
      WHEN 'wildfire' THEN f.m_wildfire
      WHEN 'tornado_severe' THEN f.m_tornado
      WHEN 'winter' THEN f.m_winter
      WHEN 'earthquake' THEN f.m_earthquake
      ELSE NULL
    END AS DOUBLE) AS matched_dominant
  FROM cs1 cs
  JOIN geo.state_ref sr ON sr.state_abbr = cs.state_abbr
  JOIN flags f ON f.cik = cs.cik AND f.accession_number = cs.accession_number
  LEFT JOIN dom1 dm ON dm.state_fips = sr.state_fips
  LEFT JOIN state_totals st ON st.state_fips = sr.state_fips
)
SELECT count(*) AS n_companies,
  AVG(matched_dominant) AS match_rate_dominant_hazard,
  AVG(m_climate) AS pct_mention_climate_change,
  AVG(m_hurricane) AS pct_hurricane, AVG(m_flood) AS pct_flood, AVG(m_wildfire) AS pct_wildfire,
  AVG(m_tornado) AS pct_tornado_severe, AVG(m_winter) AS pct_winter, AVG(m_earthquake) AS pct_earthquake,
  corr(total_declarations, m_climate) AS corr_disasters_vs_climate_mention
FROM joined
query — 5 rows — 34342 ms

WITH company_state AS (
  SELECT fm.cik, fm.accession_number,
    REGEXP_REPLACE(fm.mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr,
    ROW_NUMBER() OVER (PARTITION BY fm.cik ORDER BY fm.filing_date DESC) AS rn
  FROM sec.filing_metadata fm
  WHERE fm.filing_type='10-K' AND fm."year"=2024 AND fm.mailing_address IS NOT NULL
),
cs1 AS (SELECT cik, accession_number, state_abbr FROM company_state WHERE rn=1),
flags AS (
  SELECT cik, accession_number,
    MAX(CASE WHEN paragraph_text ILIKE '%hurricane%' OR paragraph_text ILIKE '%tropical storm%' THEN 1 ELSE 0 END) AS m_hurricane,
    MAX(CASE WHEN paragraph_text ILIKE '%flood%' THEN 1 ELSE 0 END) AS m_flood,
    MAX(CASE WHEN paragraph_text ILIKE '%wildfire%' THEN 1 ELSE 0 END) AS m_wildfire,
    MAX(CASE WHEN paragraph_text ILIKE '%tornado%' OR paragraph_text ILIKE '%severe storm%' THEN 1 ELSE 0 END) AS m_tornado,
    MAX(CASE WHEN paragraph_text ILIKE '%winter storm%' OR paragraph_text ILIKE '%severe ice storm%' OR paragraph_text ILIKE '%snowstorm%' THEN 1 ELSE 0 END) AS m_winter,
    MAX(CASE WHEN paragraph_text ILIKE '%earthquake%' THEN 1 ELSE 0 END) AS m_earthquake,
    MAX(CASE WHEN paragraph_text ILIKE '%climate change%' THEN 1 ELSE 0 END) AS m_climate
  FROM sec.risk_factor_sections
  WHERE "year"=2024
  GROUP BY cik, accession_number
),
state_hazard AS (
  SELECT state_fips,
    CASE
      WHEN incident_type IN ('Hurricane','Tropical Storm','Coastal Storm','Typhoon') THEN 'hurricane'
      WHEN incident_type IN ('Flood','Dam/Levee Break') THEN 'flood'
      WHEN incident_type = 'Fire' THEN 'wildfire'
      WHEN incident_type IN ('Tornado','Severe Storm','Straight-Line Winds') THEN 'tornado_severe'
      WHEN incident_type IN ('Winter Storm','Snowstorm','Severe Ice Storm') THEN 'winter'
      WHEN incident_type = 'Earthquake' THEN 'earthquake'
      WHEN incident_type = 'Mud/Landslide' THEN 'mudslide'
      ELSE 'other'
    END AS hazard_cat,
    count(*) AS n
  FROM disasters.disaster_declarations
  WHERE CAST("year" AS INTEGER) BETWEEN 2015 AND 2024
  GROUP BY state_fips,
    CASE
      WHEN incident_type IN ('Hurricane','Tropical Storm','Coastal Storm','Typhoon') THEN 'hurricane'
      WHEN incident_type IN ('Flood','Dam/Levee Break') THEN 'flood'
      WHEN incident_type = 'Fire' THEN 'wildfire'
      WHEN incident_type IN ('Tornado','Severe Storm','Straight-Line Winds') THEN 'tornado_severe'
      WHEN incident_type IN ('Winter Storm','Snowstorm','Severe Ice Storm') THEN 'winter'
      WHEN incident_type = 'Earthquake' THEN 'earthquake'
      WHEN incident_type = 'Mud/Landslide' THEN 'mudslide'
      ELSE 'other'
    END
),
dominant AS (
  SELECT state_fips, hazard_cat, n,
    ROW_NUMBER() OVER (PARTITION BY state_fips ORDER BY n DESC) AS rk
  FROM state_hazard WHERE hazard_cat <> 'other'
),
dom1 AS (SELECT state_fips, hazard_cat AS dominant_hazard, n AS dom_count FROM dominant WHERE rk=1),
joined AS (
  SELECT cs.cik, cs.state_abbr, sr.state_fips, dm.dominant_hazard,
    CAST(f.m_hurricane AS DOUBLE) AS m_hurricane, CAST(f.m_flood AS DOUBLE) AS m_flood,
    CAST(f.m_wildfire AS DOUBLE) AS m_wildfire, CAST(f.m_tornado AS DOUBLE) AS m_tornado,
    CAST(f.m_winter AS DOUBLE) AS m_winter, CAST(f.m_earthquake AS DOUBLE) AS m_earthquake,
    CAST(f.m_climate AS DOUBLE) AS m_climate,
    CAST(CASE dm.dominant_hazard
      WHEN 'hurricane' THEN f.m_hurricane
      WHEN 'flood' THEN f.m_flood
      WHEN 'wildfire' THEN f.m_wildfire
      WHEN 'tornado_severe' THEN f.m_tornado
      WHEN 'winter' THEN f.m_winter
      WHEN 'earthquake' THEN f.m_earthquake
      ELSE NULL
    END AS DOUBLE) AS matched_dominant
  FROM cs1 cs
  JOIN geo.state_ref sr ON sr.state_abbr = cs.state_abbr
  JOIN flags f ON f.cik = cs.cik AND f.accession_number = cs.accession_number
  LEFT JOIN dom1 dm ON dm.state_fips = sr.state_fips
)
SELECT dominant_hazard, count(*) AS n_companies, AVG(matched_dominant) AS match_rate,
  AVG(m_earthquake) AS pct_mention_earthquake_regardless
FROM joined
GROUP BY dominant_hazard
ORDER BY n_companies DESC
query — 1 rows — 3113 ms

SELECT
  (SELECT count(DISTINCT cik) FROM sec.filing_metadata WHERE filing_type='10-K' AND "year"=2024) AS total_2024_10k_ciks,
  (SELECT count(DISTINCT cik) FROM sec.filing_metadata WHERE filing_type='10-K' AND "year"=2024 AND mailing_address IS NULL) AS null_address_ciks

Sources

  1. AskAmerica: sec.risk_factor_sections keyword flags by company (2024 10-Ks)
    Show SQL
    WITH flags AS (SELECT cik, accession_number, MAX(CASE WHEN paragraph_text ILIKE '%hurricane%' OR paragraph_text ILIKE '%tropical storm%' THEN 1 ELSE 0 END) AS m_hurricane, MAX(CASE WHEN paragraph_text ILIKE '%flood%' THEN 1 ELSE 0 END) AS m_flood, MAX(CASE WHEN paragraph_text ILIKE '%wildfire%' THEN 1 ELSE 0 END) AS m_wildfire, MAX(CASE WHEN paragraph_text ILIKE '%tornado%' OR paragraph_text ILIKE '%severe storm%' THEN 1 ELSE 0 END) AS m_tornado, MAX(CASE WHEN paragraph_text ILIKE '%winter storm%' OR paragraph_text ILIKE '%severe ice storm%' OR paragraph_text ILIKE '%snowstorm%' THEN 1 ELSE 0 END) AS m_winter, MAX(CASE WHEN paragraph_text ILIKE '%earthquake%' THEN 1 ELSE 0 END) AS m_earthquake, MAX(CASE WHEN paragraph_text ILIKE '%climate change%' THEN 1 ELSE 0 END) AS m_climate FROM sec.risk_factor_sections WHERE "year"=2024 GROUP BY cik, accession_number) SELECT * FROM flags
  2. AskAmerica: FEMA dominant hazard type per state, 2015-2024
    Show SQL
    SELECT state_fips, incident_type, count(*) FROM disasters.disaster_declarations WHERE CAST("year" AS INTEGER) BETWEEN 2015 AND 2024 GROUP BY state_fips, incident_type
  3. AskAmerica: company HQ state from SEC filing mailing address
    Show SQL
    SELECT cik, accession_number, REGEXP_REPLACE(mailing_address, '.*, ([A-Z]{2}) [0-9]{5}(-[0-9]{4})?$', '\1') AS state_abbr FROM sec.filing_metadata WHERE filing_type='10-K' AND "year"=2024 AND mailing_address IS NOT NULL
  4. SEC rulemaking record: climate disclosures called boilerplate, not company-specific (Deloitte/Berkeley Law summaries of SEC 2024 climate rule) — Secondary summary of SEC rulemaking commentary, fetched 2026-09-10
  5. 97% of Fortune 500 mention climate change but mostly in general terms (search-summarized secondary source) — Found via WebSearch summary; not independently re-parsed as a primary document in this session
  6. Linking physical climate risk with mandatory business risk disclosure requirements (IOPscience, 2024) — Direct fetch failed (HTTP 400) — cited as a relevant published study by title only, its figures are NOT used in this report