Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 60 additions & 1 deletion dbt/models/default/default.vw_card_res_char.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,58 @@ WITH multicodes AS (
GROUP BY parid, taxyr
),

-- Gather HIE start and end years from both ADDN and OBY tables. We need to
-- stack them to properly count the number of active and expiring HIEs for each
-- PIN-year combination below. We define unique start and end dates within cards
-- as separate HIEs.
all_hies AS (
SELECT DISTINCT
parid AS pin,
card,
taxyr AS year,
CAST(taxyr AS INT) AS year_int,
userval1 AS hie_start,
userval2 AS hie_end
FROM {{ source('iasworld', 'addn') }}
WHERE lline > 0
AND cur = 'Y'
AND deactivat IS NULL
AND userval1 IS NOT NULL
AND userval2 IS NOT NULL
UNION ALL
SELECT DISTINCT
parid AS pin,
card,
taxyr AS year,
CAST(taxyr AS INT) AS year_int,
CAST(user10 AS INT) AS hie_start,
CAST(user14 AS INT) AS hie_end
FROM {{ source('iasworld', 'oby') }}
WHERE cur = 'Y'
AND deactivat IS NULL
AND user10 IS NOT NULL
AND user14 IS NOT NULL
AND class = '288'
),

hies AS (
SELECT
pin,
year,
SUM(
CAST(
-- HIE adjustments to AVs in iasworld.asmt include the start and
-- end years, so we use a between statement here.
Comment on lines +55 to +56
Copy link
Member Author

@wrridgeway wrridgeway Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use mailed_hie from default.vw_pin_value to confirm these start/end dates are inclusive:

select vpv.pin,
	vpv.year,
	vpv.mailed_hie,
	oby.user10,
	oby.user14
from default.vw_pin_value vpv
	left join iasworld.oby on vpv.pin = oby.parid
	and vpv.year = oby.taxyr
	and oby.cur = 'Y'
	and oby.deactivat is null
	and oby.class = '288'
where vpv.pin = '01012130010000'
and vpv.year >= '2019'
order by vpv.year desc
pin year mailed_hie user10 user14
01012130010000 2026
01012130010000 2025 0
01012130010000 2024 2352 2021 2024
01012130010000 2023 2352 2021 2024
01012130010000 2022 2352 2021 2024
01012130010000 2021 2352 2021 2024
01012130010000 2020 0
01012130010000 2019

year_int BETWEEN hie_start AND hie_end AS INT
)
) AS hie_num_active,
SUM(CAST(year_int = hie_end AS INT)) AS hie_num_expiring
Comment on lines +57 to +60
Copy link
Member

@jeancochrane jeancochrane Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Thought, non-blocking] You may have noticed this already, but heads up that there are some obviously incorrect dates in the hie_start and hie_end fields between the two tables, which will cause HIE counts greater than 0 for a handful of PINs:

hie_start query
select
    hie_start,
    count(*) as cnt
from (
    SELECT
        taxyr AS year,
        CAST(userval1 AS INT) AS hie_start
    FROM iasworld.addn
    WHERE lline > 0
        AND cur = 'Y'
        AND deactivat IS NULL
        AND userval1 IS NOT NULL
        AND userval2 IS NOT NULL
    union all
    SELECT
        taxyr AS year,
        CAST(user10 AS INT) AS hie_start
    FROM iasworld.oby
    WHERE cur = 'Y'
        AND deactivat IS NULL
        AND user10 IS NOT NULL
        AND user14 IS NOT NULL
        AND class = '288'
) as all_hie
where hie_start not between 2000 and 2026
group by 1
order by 1
hie_start cnt
204 3
2030 3
2032 20
2033 4
2053 4
2055 3
hie_end query
select
    hie_end,
    count(*) as cnt
from (
    SELECT
        taxyr AS year,
        CAST(userval2 AS INT) AS hie_end
    FROM iasworld.addn
    WHERE lline > 0
        AND cur = 'Y'
        AND deactivat IS NULL
        AND userval1 IS NOT NULL
        AND userval2 IS NOT NULL
    union all
    SELECT
        taxyr AS year,
        CAST(user14 AS INT) AS hie_end
    FROM iasworld.oby
    WHERE cur = 'Y'
        AND deactivat IS NULL
        AND user10 IS NOT NULL
        AND user14 IS NOT NULL
        AND class = '288'
) as all_hie
where hie_end not between 2022 and 2032
group by 1
order by 1
hie_end cnt
2205 4

There are few enough of these that it feels like it might be possible to get Valuations to fix them. But I wonder if it's worth it, since there are so few? If we think it's worth it, we could pull this out into a separate view and add some data integrity tests on top of it.

FROM all_hies
GROUP BY
pin,
year
),

-- Conditionals in CTE do not ensure distinct outputs
pools AS (
SELECT
Expand Down Expand Up @@ -129,7 +181,11 @@ SELECT
-- This is a brand new characteristic being collected by Valuations and we
-- are not yet confident about its completeness or accuracy.
-- This is not currently being used in open data or modeling.
COALESCE(pools.in_ground_pool, FALSE) AS char_in_ground_pool
COALESCE(pools.in_ground_pool, FALSE) AS char_in_ground_pool,

-- HIE data
COALESCE(hies.hie_num_active, 0) AS hie_num_active,
COALESCE(hies.hie_num_expiring, 0) AS hie_num_expiring

FROM {{ source('iasworld', 'pardat') }} AS par
INNER JOIN {{ source('iasworld', 'dweldat') }} AS dwel
Expand All @@ -151,6 +207,9 @@ LEFT JOIN {{ source('iasworld', 'legdat') }} AS leg
LEFT JOIN pools
ON dwel.parid = pools.parid
AND dwel.taxyr = pools.taxyr
LEFT JOIN hies
ON dwel.parid = hies.pin
AND dwel.taxyr = hies.year
WHERE par.cur = 'Y'
AND par.deactivat IS NULL
AND par.class NOT IN ('999')
4 changes: 4 additions & 0 deletions dbt/models/default/schema/default.vw_card_res_char.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ models:
description: '{{ doc("shared_column_char_yrblt") }}'
- name: class
description: '{{ doc("shared_column_class") }}'
- name: hie_num_active
description: '{{ doc("shared_column_hie_num_active") }}'
- name: hie_num_expiring
description: '{{ doc("shared_column_hie_num_expiring") }}'
- name: pin
description: '{{ doc("shared_column_pin") }}'
- name: pin10
Expand Down
12 changes: 12 additions & 0 deletions dbt/models/iasworld/columns.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,18 @@ Group adjustment value
Homesite indicator
{% enddocs %}

## hie_end

{% docs column_hie_end %}
Home improvement exemption end year
{% enddocs %}

## hie_start

{% docs column_hie_start %}
Home improvement exemption start year
{% enddocs %}

## iasw_id

{% docs column_iasw_id %}
Expand Down
17 changes: 17 additions & 0 deletions dbt/models/iasworld/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ Control table for `asmt` admin module - multi-jurisdiction version.
Residential additions. Stores data about Home Improvement Exemptions (HIEs)
and other information about `iasworld.dweldat` properties.

### Nuance

- In order to isolate HIEs, condition on `lline > 0`
- HIEs from `addn` can be joined to dweldat by card
- The characteristic changes in `addn` are applied immediately to the
corresponding `dweldat` characteristics rather then when HIEs "roll off".
- Individual HIEs are defined within start/end year and card

**Primary Key**: `jur`, `taxyr`, `parid`, `card`, `lline`
{% enddocs %}

Expand Down Expand Up @@ -298,6 +306,15 @@ Taxpayer information such as name and mailing address.
Outbuilding table. This is the main storage table for condo unit-level data.
It also stores other miscellaneous sub-PIN information like HIEs.

### Nuance

- In order to isolate HIEs, condition on `class = '288'`
- HIEs from `oby` cannot necessarily be joined to `dweldat` by card, though that
is the intended behavior
- The characteristic changes in `oby` are applied immediately to the
corresponding `dweldat` characteristics rather then when HIEs "roll off".
Comment on lines +311 to +315
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mirella confirmed this is the case for addn, Ray confirmed it's the case for oby.

- Individual HIEs are defined within start/end year and card

**Primary Key**: `jur`, `taxyr`, `parid`, `card`, `lline`
{% enddocs %}

Expand Down
4 changes: 4 additions & 0 deletions dbt/models/iasworld/schema/iasworld.addn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ sources:
description: '{{ doc("column_trans_id") }}'
- name: upd_status
description: '{{ doc("column_upd_status") }}'
- name: userval1
description: '{{ doc("column_hie_start") }}'
- name: userval2
description: '{{ doc("column_hie_end") }}'
- name: value
description: Value of the addition
- name: vect
Expand Down
4 changes: 4 additions & 0 deletions dbt/models/iasworld/schema/iasworld.oby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,10 @@ sources:
description: Number of identical units
- name: upd_status
description: '{{ doc("column_upd_status") }}'
- name: user10
description: '{{ doc("column_hie_start") }}'
- name: user14
description: '{{ doc("column_hie_end") }}'
- name: user16
description: '{{ doc("shared_column_alternative_cdu") }}'
- name: valmeth
Expand Down
4 changes: 4 additions & 0 deletions dbt/models/model/model.vw_card_res_input.sql
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ forward_fill AS (
ch.char_ncu,
ch.char_tp_plan,
ch.char_recent_renovation,
ch.hie_num_active,
ch.hie_num_expiring,

-- Land and lot size indicators
sp.char_land_sf_95_percentile,
Expand Down Expand Up @@ -216,6 +218,8 @@ SELECT
f1.char_ncu,
f1.char_tp_plan,
f1.char_recent_renovation,
f1.hie_num_active,
f1.hie_num_expiring,
Comment on lines +221 to +222
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Question, non-blocking] Somehow we're ending up with nulls here. Is that a problem?

select count(*)
from z_ci_add_hies_to_shared_model_view_model.vw_card_res_input
where hie_num_active is null or hie_num_expiring is null
> 185

Copy link
Member Author

@wrridgeway wrridgeway Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this too. There are no nulls in default.vw_card_res_char. It's a consequence of class mismatches between dweldat and pardat. For example pin 19321300500000 is not in dweldat after 2020 because it switched from class 202 to class 100. But it was still class 202 in pardat in 2021. So because vw_pin_shared_input uses class from pardat for its universe but the downstream res model view draws characteristics from dweldat some pins for some years end up with nulls for for more than just the new columns.

f1.char_land_sf_95_percentile,
f1.ind_land_gte_95_percentile,
f1.char_bldg_sf_95_percentile,
Expand Down
4 changes: 4 additions & 0 deletions dbt/models/model/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,10 @@ models:
description: '{{ doc("shared_column_char_use") }}'
- name: char_yrblt
description: '{{ doc("shared_column_char_yrblt") }}'
- name: hie_num_active
description: '{{ doc("shared_column_hie_num_active") }}'
- name: hie_num_expiring
description: '{{ doc("shared_column_hie_num_expiring") }}'
- name: ind_bldg_gte_95_percentile
description: |
Indicator for a PIN with building square footage larger
Expand Down
12 changes: 12 additions & 0 deletions dbt/models/shared_columns.md
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,18 @@ Possible values for this variable are:
Year the property was constructed
{% enddocs %}

## hie_num_active

{% docs shared_column_hie_num_active %}
Number of active home improvement exemptions
{% enddocs %}

## hie_num_expiring

{% docs shared_column_hie_num_expiring %}
Number of home improvement exemptions that will expire after the current year
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize "after the current year" is a little wonky, but it seems like the most straightforward way to build this given the inclusive nature of the start/end years.

{% enddocs %}

# Cook County

## card
Expand Down
Loading