complete app
test / test (push) Successful in 9s

This commit is contained in:
2026-09-17 17:39:22 -05:00
parent 4d633a39be
commit 3d5de1dc3e
84 changed files with 24229 additions and 0 deletions
@@ -0,0 +1,21 @@
{{
config(
materialized='table',
schema='marts',
tags=["dimension"]
)
}}
WITH source AS (
SELECT arena_name, city, state_or_country, location
FROM {{ ref('arena_mappings') }}
)
SELECT
{{ dbt_utils.generate_surrogate_key(['arena_name', 'city']) }} AS arena_key,
arena_name,
city AS arena_city,
state_or_country AS arena_state_or_country,
location AS arena_location
FROM source
ORDER BY arena_name, arena_city
@@ -0,0 +1,44 @@
{{
config(
materialized='table',
schema='marts',
tags=["dimension"]
)
}}
{% set start_date_query %}
select min(game_date)::date from {{ ref('stg_games') }}
{% endset %}
{% set start_date = dbt_utils.get_single_value(start_date_query) %}
{% set end_date_query %}
select max(game_date)::date from {{ ref('stg_games') }}
{% endset %}
{% set end_date = dbt_utils.get_single_value(end_date_query) %}
WITH date_spine AS (
SELECT UNNEST(generate_series(
'{{ start_date }}'::date,
'{{ end_date }}'::date,
INTERVAL '1 day'
))::date AS date_day
)
SELECT
CAST(strftime(date_day, '%Y%m%d') AS INTEGER) AS date_key,
date_day AS full_date,
EXTRACT(YEAR FROM date_day)::int AS year,
EXTRACT(QUARTER FROM date_day)::int AS quarter_of_year,
EXTRACT(MONTH FROM date_day)::int AS month_of_year,
strftime(date_day, '%B') AS month_name,
EXTRACT(DAY FROM date_day)::int AS day_of_month,
EXTRACT(ISODOW FROM date_day)::int AS day_of_week,
strftime(date_day, '%A') AS day_of_week_name,
EXTRACT(DOY FROM date_day)::int AS day_of_year,
EXTRACT(WEEK FROM date_day)::int AS week_of_year,
CASE
WHEN EXTRACT(ISODOW FROM date_day) IN (6, 7) THEN true
ELSE false
END AS is_weekend
FROM date_spine
ORDER BY full_date
@@ -0,0 +1,36 @@
{{
config(
materialized='table',
schema='marts',
tags=["dimension"]
)
}}
WITH distinct_archetypes AS (
SELECT DISTINCT
usage_tier,
impact_tier,
shooting_efficiency_tier,
minutes_based_role,
is_double_double,
is_triple_double,
is_versatile,
is_defensive_specialist,
is_three_and_d
FROM {{ ref('int_player_performance') }}
)
SELECT
{{ dbt_utils.generate_surrogate_key([
'usage_tier',
'impact_tier',
'shooting_efficiency_tier',
'minutes_based_role',
'is_double_double',
'is_triple_double',
'is_versatile',
'is_defensive_specialist',
'is_three_and_d'
]) }} AS archetype_key,
*
FROM distinct_archetypes
@@ -0,0 +1,26 @@
{{
config(
materialized='table',
schema='marts',
tags=["dimension"]
)
}}
WITH player_game_stats AS (
SELECT
stats.player_id,
stats.player_name,
games.game_date,
ROW_NUMBER() OVER (PARTITION BY stats.player_id ORDER BY games.game_date DESC) as rn
FROM {{ ref('stg_player_game_basic_stats') }} AS stats
LEFT JOIN {{ ref('stg_games') }} AS games
ON stats.game_id = games.game_id
)
SELECT
{{ dbt_utils.generate_surrogate_key(['player_id']) }} AS player_key,
player_id,
player_name
FROM player_game_stats
WHERE rn = 1
ORDER BY player_name
@@ -0,0 +1,19 @@
{{
config(
materialized='table',
schema='marts',
tags=["dimension"]
)
}}
WITH all_seasons AS (
SELECT DISTINCT season_start_year
FROM {{ ref('int_games_enriched') }}
)
SELECT
{{ dbt_utils.generate_surrogate_key(['season_start_year']) }} AS season_key,
season_start_year,
season_start_year || '-' || SUBSTR(CAST(season_start_year + 1 AS VARCHAR), 3, 2) AS season_display
FROM all_seasons
ORDER BY season_start_year
@@ -0,0 +1,32 @@
{{
config(
materialized='table',
schema='marts',
tags=["dimension"]
)
}}
WITH zones AS (
SELECT * FROM (
VALUES
('At Rim (0-3 ft)', 0, 3, 1, 'Paint', 'Interior', 'Field Goal'),
('Short Range (4-10 ft)', 4, 10, 2, 'Paint', 'Interior', 'Field Goal'),
('Mid Range (11-16 ft)', 11, 16, 3, 'Mid Range', 'Mid Range', 'Field Goal'),
('Long Mid Range (17-23 ft)', 17, 23, 4, 'Mid Range', 'Mid Range', 'Field Goal'),
('Three Point (24-27 ft)', 24, 27, 5, 'Perimeter', 'Three Point', 'Field Goal'),
('Deep Three (28+ ft)', 28, 50, 6, 'Perimeter', 'Three Point', 'Field Goal'),
('Free Throw (15 ft)', 15, 15, 7, 'Free Throw', 'Free Throw', 'Free Throw')
) AS t(shot_distance_zone, min_distance_ft, max_distance_ft, zone_order, zone_group, zone_category, shot_class)
)
SELECT
{{ dbt_utils.generate_surrogate_key(['shot_distance_zone']) }} AS shot_zone_key,
shot_distance_zone,
min_distance_ft,
max_distance_ft,
zone_order,
zone_group,
zone_category,
shot_class
FROM zones
ORDER BY zone_order
@@ -0,0 +1,19 @@
{{
config(
materialized='table',
schema='marts',
tags=["dimension"]
)
}}
WITH team_mappings AS (
SELECT team_abbr, full_name
FROM {{ ref('team_maps') }}
)
SELECT
{{ dbt_utils.generate_surrogate_key(['team_abbr']) }} AS team_key,
team_abbr,
full_name AS team_full_name
FROM team_mappings
ORDER BY team_abbr
@@ -0,0 +1,50 @@
{{
config(
materialized='incremental',
schema='marts',
unique_key='game_key',
tags=["fact"]
)
}}
WITH games_enriched AS (
SELECT *
FROM {{ ref('int_games_enriched') }}
{% if is_incremental() %}
WHERE game_date >= (SELECT MAX(game_date) FROM {{ this }}) - INTERVAL '30 days'
{% endif %}
)
SELECT
{{ dbt_utils.generate_surrogate_key(['ge.game_id']) }} AS game_key,
d.date_key,
s.season_key,
a.arena_key,
home_team.team_key AS home_team_key,
visitor_team.team_key AS visitor_team_key,
winning_team.team_key AS winning_team_key,
ge.game_id,
ge.home_points,
ge.visitor_points,
ge.point_differential,
ge.total_points,
ge.is_playoff,
ge.is_overtime,
CASE WHEN ge.home_points > ge.visitor_points THEN TRUE ELSE FALSE END AS is_home_team_winner,
ge.home_net_rating,
ge.visitor_net_rating,
ge.matchup_pace,
CASE
WHEN ge.point_differential <= 5 THEN 'Clutch Game'
WHEN ge.point_differential <= 10 THEN 'Competitive'
WHEN ge.point_differential <= 20 THEN 'Decisive'
ELSE 'Blowout'
END AS game_competitiveness_tier,
CAST(ge.game_date AS DATE) AS game_date
FROM games_enriched AS ge
LEFT JOIN {{ ref('dim_dates') }} AS d ON CAST(ge.game_date AS DATE) = d.full_date
LEFT JOIN {{ ref('dim_seasons') }} AS s ON ge.season_start_year = s.season_start_year
LEFT JOIN {{ ref('dim_arenas') }} AS a ON ge.arena = a.arena_name AND ge.arena_city = a.arena_city
LEFT JOIN {{ ref('dim_teams') }} AS home_team ON ge.home_team = home_team.team_abbr
LEFT JOIN {{ ref('dim_teams') }} AS visitor_team ON ge.visitor_team = visitor_team.team_abbr
LEFT JOIN {{ ref('dim_teams') }} AS winning_team ON ge.winning_team = winning_team.team_abbr
@@ -0,0 +1,175 @@
{{
config(
materialized='incremental',
schema='marts',
unique_key='player_game_shooting_key',
tags=["fact"]
)
}}
WITH shots AS (
SELECT *
FROM {{ ref('int_player_shots_enriched') }}
WHERE has_game_match = TRUE
{% if is_incremental() %}
AND game_date >= (SELECT MAX(game_date) FROM {{ this }}) - INTERVAL '30 days'
{% endif %}
),
game_agg AS (
SELECT
game_id, player_id, team, opponent,
MIN(game_date) AS game_date,
MIN(season_start_year) AS season_start_year,
BOOL_OR(is_playoff) AS is_playoff,
MIN(team_location) AS team_location,
MIN(game_result) AS game_result,
SUM(points_generated) AS total_points,
COUNT(*) AS total_shot_attempts,
SUM(shot_made_flag) AS total_shots_made,
COUNT(*) FILTER (WHERE shot_source = 'shot_chart') AS fg_attempts,
SUM(shot_made_flag) FILTER (WHERE shot_source = 'shot_chart') AS fg_makes,
CASE WHEN COUNT(*) FILTER (WHERE shot_source = 'shot_chart') > 0
THEN SUM(shot_made_flag) FILTER (WHERE shot_source = 'shot_chart')::DECIMAL
/ COUNT(*) FILTER (WHERE shot_source = 'shot_chart')::DECIMAL
ELSE 0
END AS fg_pct,
SUM(points_generated) FILTER (WHERE shot_source = 'shot_chart') AS fg_points,
COUNT(*) FILTER (WHERE shot_source = 'box_score_ft') AS ft_attempts,
SUM(shot_made_flag) FILTER (WHERE shot_source = 'box_score_ft') AS ft_makes,
CASE WHEN COUNT(*) FILTER (WHERE shot_source = 'box_score_ft') > 0
THEN SUM(shot_made_flag) FILTER (WHERE shot_source = 'box_score_ft')::DECIMAL
/ COUNT(*) FILTER (WHERE shot_source = 'box_score_ft')::DECIMAL
ELSE 0
END AS ft_pct,
SUM(points_generated) FILTER (WHERE shot_source = 'box_score_ft') AS ft_points,
COUNT(*) FILTER (WHERE is_three_pointer = FALSE AND shot_source = 'shot_chart') AS two_point_attempts,
SUM(shot_made_flag) FILTER (WHERE is_three_pointer = FALSE AND shot_source = 'shot_chart') AS two_point_makes,
CASE WHEN COUNT(*) FILTER (WHERE is_three_pointer = FALSE AND shot_source = 'shot_chart') > 0
THEN SUM(shot_made_flag) FILTER (WHERE is_three_pointer = FALSE AND shot_source = 'shot_chart')::DECIMAL
/ COUNT(*) FILTER (WHERE is_three_pointer = FALSE AND shot_source = 'shot_chart')::DECIMAL
ELSE 0
END AS two_point_fg_pct,
COUNT(*) FILTER (WHERE is_three_pointer = TRUE) AS three_point_attempts,
SUM(shot_made_flag) FILTER (WHERE is_three_pointer = TRUE) AS three_point_makes,
CASE WHEN COUNT(*) FILTER (WHERE is_three_pointer = TRUE) > 0
THEN SUM(shot_made_flag) FILTER (WHERE is_three_pointer = TRUE)::DECIMAL
/ COUNT(*) FILTER (WHERE is_three_pointer = TRUE)::DECIMAL
ELSE 0
END AS three_point_fg_pct,
COUNT(*) FILTER (WHERE shot_distance_zone = 'At Rim (0-3 ft)') AS at_rim_attempts,
SUM(shot_made_flag) FILTER (WHERE shot_distance_zone = 'At Rim (0-3 ft)') AS at_rim_makes,
CASE WHEN COUNT(*) FILTER (WHERE shot_distance_zone = 'At Rim (0-3 ft)') > 0
THEN SUM(shot_made_flag) FILTER (WHERE shot_distance_zone = 'At Rim (0-3 ft)')::DECIMAL
/ COUNT(*) FILTER (WHERE shot_distance_zone = 'At Rim (0-3 ft)')::DECIMAL
ELSE 0
END AS at_rim_fg_pct,
COUNT(*) FILTER (WHERE is_clutch_shot = TRUE) AS clutch_fg_attempts,
SUM(shot_made_flag) FILTER (WHERE is_clutch_shot = TRUE) AS clutch_fg_makes,
CASE WHEN COUNT(*) FILTER (WHERE is_clutch_shot = TRUE) > 0
THEN SUM(shot_made_flag) FILTER (WHERE is_clutch_shot = TRUE)::DECIMAL
/ COUNT(*) FILTER (WHERE is_clutch_shot = TRUE)::DECIMAL
ELSE 0
END AS clutch_fg_pct,
CASE WHEN COUNT(*) FILTER (WHERE shot_source = 'shot_chart') > 0
THEN COUNT(*) FILTER (WHERE is_three_pointer = TRUE)::DECIMAL
/ COUNT(*) FILTER (WHERE shot_source = 'shot_chart')::DECIMAL
ELSE 0
END AS three_point_rate,
CASE WHEN COUNT(*) FILTER (WHERE shot_source = 'shot_chart') > 0
THEN COUNT(*) FILTER (WHERE shot_distance_zone = 'At Rim (0-3 ft)')::DECIMAL
/ COUNT(*) FILTER (WHERE shot_source = 'shot_chart')::DECIMAL
ELSE 0
END AS at_rim_rate,
CASE WHEN COUNT(*) FILTER (WHERE shot_source = 'shot_chart') > 0
THEN COUNT(*) FILTER (WHERE shot_distance_zone IN ('Mid Range (11-16 ft)', 'Long Mid Range (17-23 ft)'))::DECIMAL
/ COUNT(*) FILTER (WHERE shot_source = 'shot_chart')::DECIMAL
ELSE 0
END AS mid_range_rate,
AVG(distance_ft) FILTER (WHERE shot_source = 'shot_chart') AS avg_fg_distance_ft,
CASE WHEN (
COUNT(*) FILTER (WHERE shot_source = 'shot_chart')
+ 0.44 * COUNT(*) FILTER (WHERE shot_source = 'box_score_ft')
) > 0
THEN SUM(points_generated)::DECIMAL / (
2.0 * (
COUNT(*) FILTER (WHERE shot_source = 'shot_chart')
+ 0.44 * COUNT(*) FILTER (WHERE shot_source = 'box_score_ft')
)
)
ELSE 0
END AS true_shooting_pct
FROM shots
GROUP BY game_id, player_id, team, opponent
),
final AS (
SELECT
{{ dbt_utils.generate_surrogate_key(['ga.game_id', 'ga.player_id']) }} AS player_game_shooting_key,
p.player_key,
t.team_key,
opp_t.team_key AS opponent_key,
d.date_key,
s.season_key,
ga.game_id,
ga.is_playoff,
ga.team_location,
ga.game_result,
ga.total_points,
ga.total_shot_attempts,
ga.total_shots_made,
ga.fg_attempts,
ga.fg_makes,
ga.fg_pct,
ga.fg_points,
ga.ft_attempts,
ga.ft_makes,
ga.ft_pct,
ga.ft_points,
ga.true_shooting_pct,
ga.two_point_attempts,
ga.two_point_makes,
ga.two_point_fg_pct,
ga.three_point_attempts,
ga.three_point_makes,
ga.three_point_fg_pct,
ga.at_rim_attempts,
ga.at_rim_makes,
ga.at_rim_fg_pct,
ga.clutch_fg_attempts,
ga.clutch_fg_makes,
ga.clutch_fg_pct,
ga.three_point_rate,
ga.at_rim_rate,
ga.mid_range_rate,
ga.avg_fg_distance_ft,
CASE
WHEN ga.three_point_rate >= 0.50 THEN 'Perimeter Heavy'
WHEN ga.at_rim_rate >= 0.50 THEN 'Rim Attacker'
WHEN ga.mid_range_rate >= 0.40 THEN 'Mid Range Heavy'
WHEN ga.three_point_rate >= 0.35 AND ga.at_rim_rate >= 0.30 THEN 'Modern (Rim & Three)'
ELSE 'Balanced'
END AS shot_profile_type,
CAST(ga.game_date AS DATE) AS game_date
FROM game_agg AS ga
LEFT JOIN {{ ref('dim_players') }} AS p ON ga.player_id = p.player_id
LEFT JOIN {{ ref('dim_teams') }} AS t ON ga.team = t.team_abbr
LEFT JOIN {{ ref('dim_teams') }} AS opp_t ON ga.opponent = opp_t.team_abbr
LEFT JOIN {{ ref('dim_dates') }} AS d ON CAST(ga.game_date AS DATE) = d.full_date
LEFT JOIN {{ ref('dim_seasons') }} AS s ON ga.season_start_year = s.season_start_year
)
SELECT * FROM final
@@ -0,0 +1,71 @@
{{
config(
materialized='incremental',
schema='marts',
unique_key='player_game_key',
tags=["fact"]
)
}}
WITH player_performance AS (
SELECT * FROM {{ ref('int_player_performance') }}
),
game_details AS (
SELECT game_id, arena AS arena_name, arena_city
FROM {{ ref('int_games_enriched') }}
),
final AS (
SELECT
{{ dbt_utils.generate_surrogate_key(['pp.game_id', 'pp.player_id']) }} AS player_game_key,
p.player_key,
t.team_key,
d.date_key,
s.season_key,
a.arena_key,
arch.archetype_key,
pp.game_id,
pp.minutes_played,
pp.points,
pp.assists,
pp.total_rebounds,
pp.steals,
pp.blocks,
pp.turnovers,
pp.plus_minus,
pp.net_rating,
pp.box_plus_minus,
pp.field_goals_made,
pp.field_goals_attempted,
pp.three_pointers_made,
pp.three_pointers_attempted,
pp.true_shooting_pct,
pp.effective_fg_pct,
pp.usage_pct,
pp.offensive_rating,
pp.defensive_rating,
CAST(pp.game_date AS DATE) AS game_date
FROM player_performance AS pp
LEFT JOIN game_details AS gd ON pp.game_id = gd.game_id
LEFT JOIN {{ ref('dim_player_game_archetypes') }} AS arch
ON pp.usage_tier = arch.usage_tier
AND pp.impact_tier = arch.impact_tier
AND pp.shooting_efficiency_tier = arch.shooting_efficiency_tier
AND pp.minutes_based_role = arch.minutes_based_role
AND pp.is_double_double = arch.is_double_double
AND pp.is_triple_double = arch.is_triple_double
AND pp.is_versatile = arch.is_versatile
AND pp.is_defensive_specialist = arch.is_defensive_specialist
AND pp.is_three_and_d = arch.is_three_and_d
LEFT JOIN {{ ref('dim_players') }} AS p ON pp.player_id = p.player_id
LEFT JOIN {{ ref('dim_teams') }} AS t ON pp.team = t.team_abbr
LEFT JOIN {{ ref('dim_dates') }} AS d ON CAST(pp.game_date AS DATE) = d.full_date
LEFT JOIN {{ ref('dim_seasons') }} AS s ON pp.season_start_year = s.season_start_year
LEFT JOIN {{ ref('dim_arenas') }} AS a ON gd.arena_name = a.arena_name AND gd.arena_city = a.arena_city
{% if is_incremental() %}
WHERE pp.game_date >= (SELECT MAX(game_date) FROM {{ this }}) - INTERVAL '30 days'
{% endif %}
)
SELECT * FROM final
@@ -0,0 +1,62 @@
{{
config(
materialized='incremental',
schema='marts',
unique_key='shot_key',
tags=["fact"]
)
}}
WITH shots_enriched AS (
SELECT *
FROM {{ ref('int_player_shots_enriched') }}
WHERE has_game_match = TRUE
{% if is_incremental() %}
AND game_date >= (SELECT MAX(game_date) FROM {{ this }}) - INTERVAL '30 days'
{% endif %}
),
final AS (
SELECT
{{ dbt_utils.generate_surrogate_key(['se.shot_id', 'se.shot_source']) }} AS shot_key,
p.player_key,
t.team_key,
opp_t.team_key AS opponent_key,
d.date_key,
s.season_key,
se.game_id,
se.shot_id,
se.shot_source,
se.is_playoff,
se.team_location,
se.game_result,
se.quarter_number,
se.is_overtime_shot,
se.seconds_remaining_in_quarter,
se.shot_x_coordinate,
se.shot_y_coordinate,
se.is_made,
se.shot_made_flag,
se.shot_missed_flag,
se.shot_type_raw AS shot_type,
se.shot_point_value,
se.is_three_pointer,
se.is_free_throw,
se.distance_ft,
se.shot_distance_zone,
se.points_generated,
se.team_had_lead,
se.team_score_at_shot,
se.opponent_score_at_shot,
se.score_margin_at_shot,
se.is_clutch_shot,
CAST(se.game_date AS DATE) AS game_date
FROM shots_enriched AS se
LEFT JOIN {{ ref('dim_players') }} AS p ON se.player_id = p.player_id
LEFT JOIN {{ ref('dim_teams') }} AS t ON se.team = t.team_abbr
LEFT JOIN {{ ref('dim_teams') }} AS opp_t ON se.opponent = opp_t.team_abbr
LEFT JOIN {{ ref('dim_dates') }} AS d ON CAST(se.game_date AS DATE) = d.full_date
LEFT JOIN {{ ref('dim_seasons') }} AS s ON se.season_start_year = s.season_start_year
)
SELECT * FROM final
@@ -0,0 +1,57 @@
{{
config(
materialized='incremental',
schema='marts',
unique_key='quarter_scoring_key',
tags=["fact"]
)
}}
WITH games AS (
SELECT game_id, game_date, season_start_year
FROM {{ ref('int_games_enriched') }}
{% if is_incremental() %}
WHERE game_date >= (SELECT MAX(game_date) FROM {{ this }}) - INTERVAL '30 days'
{% endif %}
),
unpivoted_scores AS (
{{ dbt_utils.unpivot(
relation=ref('stg_line_scores'),
cast_to='INTEGER',
exclude=['game_id', 'team', 'total_points', 'first_half_points', 'second_half_points', 'regulation_points', 'overtime_points', 'had_ot1', 'had_ot2', 'had_ot3', 'q2_momentum', 'q3_momentum', 'q4_momentum', 'max_quarter_score', 'min_quarter_score', 'best_quarter', 'created_at', 'updated_at', 'dbt_loaded_at'],
field_name='period_name',
value_name='points_scored'
) }}
WHERE game_id IN (SELECT game_id FROM games)
),
final AS (
SELECT
{{ dbt_utils.generate_surrogate_key(['team_scores.game_id', 'team_map.team_abbr', 'team_scores.period_name']) }} AS quarter_scoring_key,
d.date_key,
s.season_key,
t.team_key,
opp.team_key AS opponent_key,
team_scores.game_id,
REPLACE(UPPER(team_scores.period_name), '_POINTS', '') AS period,
team_scores.points_scored,
opponent_scores.points_scored AS opponent_points_scored,
(team_scores.points_scored - opponent_scores.points_scored) AS period_point_differential,
CAST(g.game_date AS DATE) AS game_date
FROM unpivoted_scores AS team_scores
INNER JOIN unpivoted_scores AS opponent_scores
ON team_scores.game_id = opponent_scores.game_id
AND team_scores.period_name = opponent_scores.period_name
AND team_scores.team != opponent_scores.team
INNER JOIN games AS g ON team_scores.game_id = g.game_id
LEFT JOIN {{ ref('team_maps') }} AS team_map ON team_scores.team = team_map.team_abbr
LEFT JOIN {{ ref('team_maps') }} AS opponent_map ON opponent_scores.team = opponent_map.team_abbr
LEFT JOIN {{ ref('dim_teams') }} AS t ON team_map.team_abbr = t.team_abbr
LEFT JOIN {{ ref('dim_teams') }} AS opp ON opponent_map.team_abbr = opp.team_abbr
LEFT JOIN {{ ref('dim_dates') }} AS d ON CAST(g.game_date AS DATE) = d.full_date
LEFT JOIN {{ ref('dim_seasons') }} AS s ON g.season_start_year = s.season_start_year
WHERE team_scores.points_scored IS NOT NULL
)
SELECT * FROM final
@@ -0,0 +1,54 @@
{{
config(
materialized='incremental',
schema='marts',
tags=["fact"],
unique_key='team_game_key'
)
}}
WITH team_performance AS (
SELECT * FROM {{ ref('int_team_performance') }}
),
game_details AS (
SELECT
game_id, game_date, season_start_year,
home_team, visitor_team, arena AS arena_name, arena_city
FROM {{ ref('int_games_enriched') }}
),
final AS (
SELECT
{{ dbt_utils.generate_surrogate_key(['tp.game_id', 'tp.team']) }} AS team_game_key,
t.team_key,
d.date_key,
s.season_key,
a.arena_key,
opp.team_key AS opponent_key,
tp.game_id,
(tp.team = gd.home_team) AS is_home_team,
tp.points,
tp.offensive_rating,
tp.defensive_rating,
tp.net_rating,
tp.pace,
tp.effective_fg_pct,
tp.turnover_rate,
tp.offensive_tier,
tp.defensive_tier,
CAST(gd.game_date AS DATE) AS game_date
FROM team_performance AS tp
LEFT JOIN game_details AS gd ON tp.game_id = gd.game_id
LEFT JOIN {{ ref('dim_teams') }} AS t ON tp.team = t.team_abbr
LEFT JOIN {{ ref('dim_teams') }} AS opp
ON CASE WHEN tp.team = gd.home_team THEN gd.visitor_team ELSE gd.home_team END = opp.team_abbr
LEFT JOIN {{ ref('dim_dates') }} AS d ON CAST(gd.game_date AS DATE) = d.full_date
LEFT JOIN {{ ref('dim_seasons') }} AS s ON gd.season_start_year = s.season_start_year
LEFT JOIN {{ ref('dim_arenas') }} AS a ON gd.arena_name = a.arena_name AND gd.arena_city = a.arena_city
{% if is_incremental() %}
WHERE gd.game_date >= (SELECT MAX(game_date) FROM {{ this }}) - INTERVAL '30 days'
{% endif %}
)
SELECT * FROM final