@@ -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
|
||||
Reference in New Issue
Block a user