@ken-e/dataform-youtube 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +3 -0
- package/README.md +4 -0
- package/eslint.config.js +11 -0
- package/includes/column_descriptions.js +95 -0
- package/includes/constants.js +5 -0
- package/includes/definitions/sources/stg_ytc_annotation.js +91 -0
- package/includes/definitions/sources/stg_ytc_basic.js +109 -0
- package/includes/definitions/sources/stg_ytc_cards.js +89 -0
- package/includes/definitions/sources/stg_ytc_combined.js +97 -0
- package/includes/definitions/sources/stg_ytc_demographics.js +84 -0
- package/includes/definitions/sources/stg_ytc_device_os.js +90 -0
- package/includes/definitions/sources/stg_ytc_end_screens.js +69 -0
- package/includes/definitions/sources/stg_ytc_list_basic.js +91 -0
- package/includes/definitions/sources/stg_ytc_list_combined.js +92 -0
- package/includes/definitions/sources/stg_ytc_list_device_os.js +90 -0
- package/includes/definitions/sources/stg_ytc_list_playback.js +89 -0
- package/includes/definitions/sources/stg_ytc_list_province.js +91 -0
- package/includes/definitions/sources/stg_ytc_list_traffic_source.js +89 -0
- package/includes/definitions/sources/stg_ytc_lu_annotation_type.js +37 -0
- package/includes/definitions/sources/stg_ytc_lu_card_type.js +35 -0
- package/includes/definitions/sources/stg_ytc_lu_device_types.js +33 -0
- package/includes/definitions/sources/stg_ytc_lu_end_screen_element_type.js +36 -0
- package/includes/definitions/sources/stg_ytc_lu_operating_systems.js +57 -0
- package/includes/definitions/sources/stg_ytc_lu_playback_location.js +34 -0
- package/includes/definitions/sources/stg_ytc_lu_sharing_services.js +94 -0
- package/includes/definitions/sources/stg_ytc_lu_traffic_sources.js +50 -0
- package/includes/definitions/sources/stg_ytc_playback.js +90 -0
- package/includes/definitions/sources/stg_ytc_province.js +103 -0
- package/includes/definitions/sources/stg_ytc_share_platform.js +82 -0
- package/includes/definitions/sources/stg_ytc_subtitles.js +89 -0
- package/includes/definitions/sources/stg_ytc_traffic_source.js +107 -0
- package/includes/definitions/ytc_annotation.js +65 -0
- package/includes/definitions/ytc_basic.js +74 -0
- package/includes/definitions/ytc_cards.js +66 -0
- package/includes/definitions/ytc_combined.js +113 -0
- package/includes/definitions/ytc_demographics.js +69 -0
- package/includes/definitions/ytc_demographics_views.js +80 -0
- package/includes/definitions/ytc_device_os.js +80 -0
- package/includes/definitions/ytc_end_screens.js +65 -0
- package/includes/definitions/ytc_list_basic.js +84 -0
- package/includes/definitions/ytc_list_combined.js +97 -0
- package/includes/definitions/ytc_list_device_os.js +90 -0
- package/includes/definitions/ytc_list_playback.js +86 -0
- package/includes/definitions/ytc_list_province.js +83 -0
- package/includes/definitions/ytc_list_traffic_source.js +91 -0
- package/includes/definitions/ytc_playback.js +73 -0
- package/includes/definitions/ytc_province.js +71 -0
- package/includes/definitions/ytc_share_platform.js +76 -0
- package/includes/definitions/ytc_subtitles.js +69 -0
- package/includes/definitions/ytc_traffic_source.js +73 -0
- package/includes/helpers.js +8 -0
- package/includes/project_variables.js +15 -0
- package/index.js +312 -0
- package/package.json +30 -0
- package/prettier.config.js +14 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by KEN-E, LLC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const column_descriptions = require("../column_descriptions");
|
|
6
|
+
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
return publish("ytc_end_screens", {
|
|
10
|
+
type: "incremental",
|
|
11
|
+
schema: config.datasetIntermediate,
|
|
12
|
+
tags: ["youtube", "output", "daily"],
|
|
13
|
+
bigquery: {
|
|
14
|
+
partitionBy: "interaction_date",
|
|
15
|
+
clusterBy: ["video_id", "end_screen_element_type"],
|
|
16
|
+
},
|
|
17
|
+
columns: column_descriptions.column_descriptions,
|
|
18
|
+
description: "YT Channel End Screen Report Table - Intermediate",
|
|
19
|
+
})
|
|
20
|
+
.preOps(
|
|
21
|
+
(ctx) => `
|
|
22
|
+
declare interaction_date_checkpoint default (
|
|
23
|
+
select date("${config.startDate}")
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
--Set the incremental update checkpoint based on current max partition value minus lookback.
|
|
27
|
+
set interaction_date_checkpoint = (
|
|
28
|
+
${ctx.when(
|
|
29
|
+
ctx.incremental(),
|
|
30
|
+
`select
|
|
31
|
+
least(
|
|
32
|
+
(select date_sub(current_date(), interval ${config.daysBack} day)),
|
|
33
|
+
(select date_sub(max(interaction_date), interval ${config.daysBack} day) from ${ctx.self()})
|
|
34
|
+
)`,
|
|
35
|
+
`select date("${config.startDate}")`,
|
|
36
|
+
)}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
${ctx.when(
|
|
40
|
+
ctx.incremental(),
|
|
41
|
+
`delete ${ctx.self()} where interaction_date > interaction_date_checkpoint`,
|
|
42
|
+
)}
|
|
43
|
+
`,
|
|
44
|
+
)
|
|
45
|
+
.query(
|
|
46
|
+
(ctx) => `
|
|
47
|
+
|
|
48
|
+
select
|
|
49
|
+
stg.* except (source_partition_date),
|
|
50
|
+
et.end_screen_element_type_name,
|
|
51
|
+
ifnull(titles.video_title, stg.video_id) as video_title
|
|
52
|
+
from ${ctx.ref("stg_ytc_end_screens")} as stg
|
|
53
|
+
left join ${ctx.ref("stg_ytc_lu_end_screen_element_type")} as et
|
|
54
|
+
using (end_screen_element_type)
|
|
55
|
+
left join ${ctx.ref(
|
|
56
|
+
config.titlesProject,
|
|
57
|
+
config.titlesDataset,
|
|
58
|
+
config.titlesTable,
|
|
59
|
+
)} as titles
|
|
60
|
+
using (video_id)
|
|
61
|
+
where interaction_date > interaction_date_checkpoint
|
|
62
|
+
|
|
63
|
+
`,
|
|
64
|
+
);
|
|
65
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by KEN-E, LLC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const column_descriptions = require("../column_descriptions");
|
|
6
|
+
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
return publish("ytc_list_basic", {
|
|
10
|
+
type: "incremental",
|
|
11
|
+
schema: config.datasetIntermediate,
|
|
12
|
+
tags: ["youtube", "output", "daily"],
|
|
13
|
+
bigquery: {
|
|
14
|
+
partitionBy: "interaction_date",
|
|
15
|
+
clusterBy: ["playlist_id", "video_id"],
|
|
16
|
+
},
|
|
17
|
+
columns: column_descriptions.column_descriptions,
|
|
18
|
+
description: "YT Channel Playlist Basic Report Table - Intermediate",
|
|
19
|
+
})
|
|
20
|
+
.preOps(
|
|
21
|
+
(ctx) => `
|
|
22
|
+
declare interaction_date_checkpoint default (
|
|
23
|
+
select date("${config.startDate}")
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
--Set the incremental update checkpoint based on current max partition value minus lookback.
|
|
27
|
+
set interaction_date_checkpoint = (
|
|
28
|
+
${ctx.when(
|
|
29
|
+
ctx.incremental(),
|
|
30
|
+
`select
|
|
31
|
+
least(
|
|
32
|
+
(select date_sub(current_date(), interval ${config.daysBack} day)),
|
|
33
|
+
(select date_sub(max(interaction_date), interval ${config.daysBack} day) from ${ctx.self()})
|
|
34
|
+
)`,
|
|
35
|
+
`select date("${config.startDate}")`,
|
|
36
|
+
)}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
${ctx.when(
|
|
40
|
+
ctx.incremental(),
|
|
41
|
+
`delete ${ctx.self()} where interaction_date > interaction_date_checkpoint`,
|
|
42
|
+
)}
|
|
43
|
+
`,
|
|
44
|
+
)
|
|
45
|
+
.query(
|
|
46
|
+
(ctx) => `
|
|
47
|
+
|
|
48
|
+
-- determine max possible viewing seconds per row so that percent viewed can be calculated downstream
|
|
49
|
+
with int_ex_titles as (
|
|
50
|
+
select
|
|
51
|
+
* except (source_partition_date),
|
|
52
|
+
playlist_saves_added - playlist_saves_removed as playlist_saves_net
|
|
53
|
+
from ${ctx.ref("stg_ytc_list_basic")}
|
|
54
|
+
where interaction_date > interaction_date_checkpoint
|
|
55
|
+
),
|
|
56
|
+
|
|
57
|
+
int_with_video_titles as (
|
|
58
|
+
select
|
|
59
|
+
int_ex_titles.*,
|
|
60
|
+
ifnull(titles.video_title, int_ex_titles.video_id) as video_title
|
|
61
|
+
from int_ex_titles
|
|
62
|
+
left join ${ctx.ref(
|
|
63
|
+
config.titlesProject,
|
|
64
|
+
config.titlesDataset,
|
|
65
|
+
config.titlesTable,
|
|
66
|
+
)} as titles
|
|
67
|
+
using (video_id)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
select
|
|
71
|
+
int_with_video_titles.*,
|
|
72
|
+
ifnull(playlists.playlist_title, int_with_video_titles.playlist_id) as playlist_title
|
|
73
|
+
from int_with_video_titles
|
|
74
|
+
left join ${ctx.ref(
|
|
75
|
+
config.titlesProject,
|
|
76
|
+
config.titlesDataset,
|
|
77
|
+
config.playlistTable,
|
|
78
|
+
)} as playlists
|
|
79
|
+
using (playlist_id)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
`,
|
|
83
|
+
);
|
|
84
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by KEN-E, LLC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const column_descriptions = require("../column_descriptions");
|
|
6
|
+
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
return publish("ytc_list_combined", {
|
|
10
|
+
type: "incremental",
|
|
11
|
+
schema: config.datasetIntermediate,
|
|
12
|
+
tags: ["youtube", "output", "daily"],
|
|
13
|
+
bigquery: {
|
|
14
|
+
partitionBy: "interaction_date",
|
|
15
|
+
clusterBy: ["playlist_id", "video_id"],
|
|
16
|
+
},
|
|
17
|
+
columns: column_descriptions.column_descriptions,
|
|
18
|
+
description: "YT Channel Playlist Combined Report Table - Intermediate",
|
|
19
|
+
})
|
|
20
|
+
.preOps(
|
|
21
|
+
(ctx) => `
|
|
22
|
+
declare interaction_date_checkpoint default (
|
|
23
|
+
select date("${config.startDate}")
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
set interaction_date_checkpoint = (
|
|
27
|
+
${ctx.when(
|
|
28
|
+
ctx.incremental(),
|
|
29
|
+
`select
|
|
30
|
+
least(
|
|
31
|
+
(select date_sub(current_date(), interval ${config.daysBack} day)),
|
|
32
|
+
(select date_sub(max(interaction_date), interval ${config.daysBack} day) from ${ctx.self()})
|
|
33
|
+
)`,
|
|
34
|
+
`select date("${config.startDate}")`,
|
|
35
|
+
)}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
${ctx.when(
|
|
39
|
+
ctx.incremental(),
|
|
40
|
+
`delete ${ctx.self()} where interaction_date > interaction_date_checkpoint`,
|
|
41
|
+
)}
|
|
42
|
+
`,
|
|
43
|
+
)
|
|
44
|
+
.query(
|
|
45
|
+
(ctx) => `
|
|
46
|
+
|
|
47
|
+
with int_with_lookup_names as (
|
|
48
|
+
select
|
|
49
|
+
base.* except(source_partition_date, device_type, operating_system, playback_location_type, traffic_source_type),
|
|
50
|
+
base.device_type,
|
|
51
|
+
base.operating_system,
|
|
52
|
+
base.playback_location_type,
|
|
53
|
+
base.traffic_source_type,
|
|
54
|
+
dt.device_name,
|
|
55
|
+
os.operating_system_name,
|
|
56
|
+
pl.playback_location_name,
|
|
57
|
+
ts.traffic_source_name,
|
|
58
|
+
playlist_saves_added - playlist_saves_removed as playlist_saves_net,
|
|
59
|
+
from ${ctx.ref("stg_ytc_list_combined")} as base
|
|
60
|
+
left join ${ctx.ref("stg_ytc_lu_device_types")} as dt
|
|
61
|
+
using (device_type)
|
|
62
|
+
left join ${ctx.ref("stg_ytc_lu_operating_systems")} as os
|
|
63
|
+
using (operating_system)
|
|
64
|
+
left join ${ctx.ref("stg_ytc_lu_playback_location")} as pl
|
|
65
|
+
using (playback_location_type)
|
|
66
|
+
left join ${ctx.ref("stg_ytc_lu_traffic_sources")} as ts
|
|
67
|
+
using (traffic_source_type)
|
|
68
|
+
where interaction_date > interaction_date_checkpoint
|
|
69
|
+
),
|
|
70
|
+
|
|
71
|
+
int_with_video_titles as (
|
|
72
|
+
select
|
|
73
|
+
int_with_lookup_names.*,
|
|
74
|
+
ifnull(titles.video_title, int_with_lookup_names.video_id) as video_title
|
|
75
|
+
from int_with_lookup_names
|
|
76
|
+
left join ${ctx.ref(
|
|
77
|
+
config.titlesProject,
|
|
78
|
+
config.titlesDataset,
|
|
79
|
+
config.titlesTable,
|
|
80
|
+
)} as titles
|
|
81
|
+
using (video_id)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
select
|
|
85
|
+
int_with_video_titles.*,
|
|
86
|
+
ifnull(playlists.playlist_title, int_with_video_titles.playlist_id) as playlist_title
|
|
87
|
+
from int_with_video_titles
|
|
88
|
+
left join ${ctx.ref(
|
|
89
|
+
config.titlesProject,
|
|
90
|
+
config.titlesDataset,
|
|
91
|
+
config.playlistTable,
|
|
92
|
+
)} as playlists
|
|
93
|
+
using (playlist_id)
|
|
94
|
+
|
|
95
|
+
`,
|
|
96
|
+
);
|
|
97
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by KEN-E, LLC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const column_descriptions = require("../column_descriptions");
|
|
6
|
+
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
return publish("ytc_list_device_os", {
|
|
10
|
+
type: "incremental",
|
|
11
|
+
schema: config.datasetIntermediate,
|
|
12
|
+
tags: ["youtube", "output", "daily"],
|
|
13
|
+
bigquery: {
|
|
14
|
+
partitionBy: "interaction_date",
|
|
15
|
+
clusterBy: ["playlist_id", "video_id", "device_type", "operating_system"],
|
|
16
|
+
},
|
|
17
|
+
columns: column_descriptions.column_descriptions,
|
|
18
|
+
description:
|
|
19
|
+
"YT Channel Playlist Device and OS Report Table - Intermediate",
|
|
20
|
+
})
|
|
21
|
+
.preOps(
|
|
22
|
+
(ctx) => `
|
|
23
|
+
declare interaction_date_checkpoint default (
|
|
24
|
+
select date("${config.startDate}")
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
set interaction_date_checkpoint = (
|
|
28
|
+
${ctx.when(
|
|
29
|
+
ctx.incremental(),
|
|
30
|
+
`select
|
|
31
|
+
least(
|
|
32
|
+
(select date_sub(current_date(), interval ${config.daysBack} day)),
|
|
33
|
+
(select date_sub(max(interaction_date), interval ${config.daysBack} day) from ${ctx.self()})
|
|
34
|
+
)`,
|
|
35
|
+
`select date("${config.startDate}")`,
|
|
36
|
+
)}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
${ctx.when(
|
|
40
|
+
ctx.incremental(),
|
|
41
|
+
`delete ${ctx.self()} where interaction_date > interaction_date_checkpoint`,
|
|
42
|
+
)}
|
|
43
|
+
`,
|
|
44
|
+
)
|
|
45
|
+
.query(
|
|
46
|
+
(ctx) => `
|
|
47
|
+
|
|
48
|
+
with int_with_device_os_names as (
|
|
49
|
+
select
|
|
50
|
+
base.* except(source_partition_date, device_type, operating_system),
|
|
51
|
+
base.device_type,
|
|
52
|
+
base.operating_system,
|
|
53
|
+
dt.device_name,
|
|
54
|
+
os.operating_system_name,
|
|
55
|
+
playlist_saves_added - playlist_saves_removed as playlist_saves_net
|
|
56
|
+
from ${ctx.ref("stg_ytc_list_device_os")} as base
|
|
57
|
+
left join ${ctx.ref("stg_ytc_lu_device_types")} as dt
|
|
58
|
+
using (device_type)
|
|
59
|
+
left join ${ctx.ref("stg_ytc_lu_operating_systems")} as os
|
|
60
|
+
using (operating_system)
|
|
61
|
+
where interaction_date > interaction_date_checkpoint
|
|
62
|
+
),
|
|
63
|
+
|
|
64
|
+
int_with_video_titles as (
|
|
65
|
+
select
|
|
66
|
+
int_with_device_os_names.*,
|
|
67
|
+
ifnull(titles.video_title, int_with_device_os_names.video_id) as video_title
|
|
68
|
+
from int_with_device_os_names
|
|
69
|
+
left join ${ctx.ref(
|
|
70
|
+
config.titlesProject,
|
|
71
|
+
config.titlesDataset,
|
|
72
|
+
config.titlesTable,
|
|
73
|
+
)} as titles
|
|
74
|
+
using (video_id)
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
select
|
|
78
|
+
int_with_video_titles.*,
|
|
79
|
+
ifnull(playlists.playlist_title, int_with_video_titles.playlist_id) as playlist_title
|
|
80
|
+
from int_with_video_titles
|
|
81
|
+
left join ${ctx.ref(
|
|
82
|
+
config.titlesProject,
|
|
83
|
+
config.titlesDataset,
|
|
84
|
+
config.playlistTable,
|
|
85
|
+
)} as playlists
|
|
86
|
+
using (playlist_id)
|
|
87
|
+
|
|
88
|
+
`,
|
|
89
|
+
);
|
|
90
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by KEN-E, LLC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const column_descriptions = require("../column_descriptions");
|
|
6
|
+
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
return publish("ytc_list_playback", {
|
|
10
|
+
type: "incremental",
|
|
11
|
+
schema: config.datasetIntermediate,
|
|
12
|
+
tags: ["youtube", "output", "daily"],
|
|
13
|
+
bigquery: {
|
|
14
|
+
partitionBy: "interaction_date",
|
|
15
|
+
clusterBy: ["playlist_id", "video_id", "playback_location_type"],
|
|
16
|
+
},
|
|
17
|
+
columns: column_descriptions.column_descriptions,
|
|
18
|
+
description:
|
|
19
|
+
"YT Channel Playlist Playback Location Report Table - Intermediate",
|
|
20
|
+
})
|
|
21
|
+
.preOps(
|
|
22
|
+
(ctx) => `
|
|
23
|
+
declare interaction_date_checkpoint default (
|
|
24
|
+
select date("${config.startDate}")
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
set interaction_date_checkpoint = (
|
|
28
|
+
${ctx.when(
|
|
29
|
+
ctx.incremental(),
|
|
30
|
+
`select
|
|
31
|
+
least(
|
|
32
|
+
(select date_sub(current_date(), interval ${config.daysBack} day)),
|
|
33
|
+
(select date_sub(max(interaction_date), interval ${config.daysBack} day) from ${ctx.self()})
|
|
34
|
+
)`,
|
|
35
|
+
`select date("${config.startDate}")`,
|
|
36
|
+
)}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
${ctx.when(
|
|
40
|
+
ctx.incremental(),
|
|
41
|
+
`delete ${ctx.self()} where interaction_date > interaction_date_checkpoint`,
|
|
42
|
+
)}
|
|
43
|
+
`,
|
|
44
|
+
)
|
|
45
|
+
.query(
|
|
46
|
+
(ctx) => `
|
|
47
|
+
|
|
48
|
+
with int_with_playback_names as (
|
|
49
|
+
select
|
|
50
|
+
base.* except(source_partition_date, playback_location_type),
|
|
51
|
+
base.playback_location_type,
|
|
52
|
+
pl.playback_location_name,
|
|
53
|
+
playlist_saves_added - playlist_saves_removed as playlist_saves_net
|
|
54
|
+
from ${ctx.ref("stg_ytc_list_playback")} as base
|
|
55
|
+
left join ${ctx.ref("stg_ytc_lu_playback_location")} as pl
|
|
56
|
+
using (playback_location_type)
|
|
57
|
+
where interaction_date > interaction_date_checkpoint
|
|
58
|
+
),
|
|
59
|
+
|
|
60
|
+
int_with_video_titles as (
|
|
61
|
+
select
|
|
62
|
+
int_with_playback_names.*,
|
|
63
|
+
ifnull(titles.video_title, int_with_playback_names.video_id) as video_title
|
|
64
|
+
from int_with_playback_names
|
|
65
|
+
left join ${ctx.ref(
|
|
66
|
+
config.titlesProject,
|
|
67
|
+
config.titlesDataset,
|
|
68
|
+
config.titlesTable,
|
|
69
|
+
)} as titles
|
|
70
|
+
using (video_id)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
select
|
|
74
|
+
int_with_video_titles.*,
|
|
75
|
+
ifnull(playlists.playlist_title, int_with_video_titles.playlist_id) as playlist_title
|
|
76
|
+
from int_with_video_titles
|
|
77
|
+
left join ${ctx.ref(
|
|
78
|
+
config.titlesProject,
|
|
79
|
+
config.titlesDataset,
|
|
80
|
+
config.playlistTable,
|
|
81
|
+
)} as playlists
|
|
82
|
+
using (playlist_id)
|
|
83
|
+
|
|
84
|
+
`,
|
|
85
|
+
);
|
|
86
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by KEN-E, LLC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const column_descriptions = require("../column_descriptions");
|
|
6
|
+
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
return publish("ytc_list_province", {
|
|
10
|
+
type: "incremental",
|
|
11
|
+
schema: config.datasetIntermediate,
|
|
12
|
+
tags: ["youtube", "output", "daily"],
|
|
13
|
+
bigquery: {
|
|
14
|
+
partitionBy: "interaction_date",
|
|
15
|
+
clusterBy: ["playlist_id", "video_id"],
|
|
16
|
+
},
|
|
17
|
+
columns: column_descriptions.column_descriptions,
|
|
18
|
+
description: "YT Channel Playlist Province Report Table - Intermediate",
|
|
19
|
+
})
|
|
20
|
+
.preOps(
|
|
21
|
+
(ctx) => `
|
|
22
|
+
declare interaction_date_checkpoint default (
|
|
23
|
+
select date("${config.startDate}")
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
--Set the incremental update checkpoint based on current max partition value minus lookback.
|
|
27
|
+
set interaction_date_checkpoint = (
|
|
28
|
+
${ctx.when(
|
|
29
|
+
ctx.incremental(),
|
|
30
|
+
`select
|
|
31
|
+
least(
|
|
32
|
+
(select date_sub(current_date(), interval ${config.daysBack} day)),
|
|
33
|
+
(select date_sub(max(interaction_date), interval ${config.daysBack} day) from ${ctx.self()})
|
|
34
|
+
)`,
|
|
35
|
+
`select date("${config.startDate}")`,
|
|
36
|
+
)}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
${ctx.when(
|
|
40
|
+
ctx.incremental(),
|
|
41
|
+
`delete ${ctx.self()} where interaction_date > interaction_date_checkpoint`,
|
|
42
|
+
)}
|
|
43
|
+
`,
|
|
44
|
+
)
|
|
45
|
+
.query(
|
|
46
|
+
(ctx) => `
|
|
47
|
+
|
|
48
|
+
-- Add calculated fields and join with title tables
|
|
49
|
+
with int_ex_titles as (
|
|
50
|
+
select
|
|
51
|
+
* except (source_partition_date),
|
|
52
|
+
playlist_saves_added - playlist_saves_removed as playlist_saves_net
|
|
53
|
+
from ${ctx.ref("stg_ytc_list_province")}
|
|
54
|
+
where interaction_date > interaction_date_checkpoint
|
|
55
|
+
),
|
|
56
|
+
|
|
57
|
+
int_with_video_titles as (
|
|
58
|
+
select
|
|
59
|
+
int_ex_titles.*,
|
|
60
|
+
ifnull(titles.video_title, int_ex_titles.video_id) as video_title
|
|
61
|
+
from int_ex_titles
|
|
62
|
+
left join ${ctx.ref(
|
|
63
|
+
config.titlesProject,
|
|
64
|
+
config.titlesDataset,
|
|
65
|
+
config.titlesTable,
|
|
66
|
+
)} as titles
|
|
67
|
+
using (video_id)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
select
|
|
71
|
+
int_with_video_titles.*,
|
|
72
|
+
ifnull(playlists.playlist_title, int_with_video_titles.playlist_id) as playlist_title
|
|
73
|
+
from int_with_video_titles
|
|
74
|
+
left join ${ctx.ref(
|
|
75
|
+
config.titlesProject,
|
|
76
|
+
config.titlesDataset,
|
|
77
|
+
config.playlistTable,
|
|
78
|
+
)} as playlists
|
|
79
|
+
using (playlist_id)
|
|
80
|
+
|
|
81
|
+
`,
|
|
82
|
+
);
|
|
83
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by KEN-E, LLC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const column_descriptions = require("../column_descriptions");
|
|
6
|
+
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
return publish("ytc_list_traffic_source", {
|
|
10
|
+
type: "incremental",
|
|
11
|
+
schema: config.datasetIntermediate,
|
|
12
|
+
tags: ["youtube", "output", "daily"],
|
|
13
|
+
bigquery: {
|
|
14
|
+
partitionBy: "interaction_date",
|
|
15
|
+
clusterBy: ["playlist_id", "video_id", "traffic_source_type"],
|
|
16
|
+
},
|
|
17
|
+
columns: column_descriptions.column_descriptions,
|
|
18
|
+
description:
|
|
19
|
+
"YT Channel Playlist Traffic Source Report Table - Intermediate",
|
|
20
|
+
})
|
|
21
|
+
.preOps(
|
|
22
|
+
(ctx) => `
|
|
23
|
+
declare interaction_date_checkpoint default (
|
|
24
|
+
select date("${config.startDate}")
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
set interaction_date_checkpoint = (
|
|
28
|
+
${ctx.when(
|
|
29
|
+
ctx.incremental(),
|
|
30
|
+
`select
|
|
31
|
+
least(
|
|
32
|
+
(select date_sub(current_date(), interval ${config.daysBack} day)),
|
|
33
|
+
(select date_sub(max(interaction_date), interval ${config.daysBack} day) from ${ctx.self()})
|
|
34
|
+
)`,
|
|
35
|
+
`select date("${config.startDate}")`,
|
|
36
|
+
)}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
${ctx.when(
|
|
40
|
+
ctx.incremental(),
|
|
41
|
+
`delete ${ctx.self()} where interaction_date > interaction_date_checkpoint`,
|
|
42
|
+
)}
|
|
43
|
+
`,
|
|
44
|
+
)
|
|
45
|
+
.query(
|
|
46
|
+
(ctx) => `
|
|
47
|
+
|
|
48
|
+
with int_ex_titles as (
|
|
49
|
+
select
|
|
50
|
+
* except (source_partition_date),
|
|
51
|
+
playlist_saves_added - playlist_saves_removed as playlist_saves_net
|
|
52
|
+
from ${ctx.ref("stg_ytc_list_traffic_source")}
|
|
53
|
+
where interaction_date > interaction_date_checkpoint
|
|
54
|
+
),
|
|
55
|
+
|
|
56
|
+
int_with_traffic_source as (
|
|
57
|
+
select
|
|
58
|
+
int_ex_titles.*,
|
|
59
|
+
ts.traffic_source_name
|
|
60
|
+
from int_ex_titles
|
|
61
|
+
left join ${ctx.ref("stg_ytc_lu_traffic_sources")} as ts
|
|
62
|
+
using (traffic_source_type)
|
|
63
|
+
),
|
|
64
|
+
|
|
65
|
+
int_with_video_titles as (
|
|
66
|
+
select
|
|
67
|
+
int_with_traffic_source.*,
|
|
68
|
+
ifnull(titles.video_title, int_with_traffic_source.video_id) as video_title
|
|
69
|
+
from int_with_traffic_source
|
|
70
|
+
left join ${ctx.ref(
|
|
71
|
+
config.titlesProject,
|
|
72
|
+
config.titlesDataset,
|
|
73
|
+
config.titlesTable,
|
|
74
|
+
)} as titles
|
|
75
|
+
using (video_id)
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
select
|
|
79
|
+
int_with_video_titles.*,
|
|
80
|
+
ifnull(playlists.playlist_title, int_with_video_titles.playlist_id) as playlist_title
|
|
81
|
+
from int_with_video_titles
|
|
82
|
+
left join ${ctx.ref(
|
|
83
|
+
config.titlesProject,
|
|
84
|
+
config.titlesDataset,
|
|
85
|
+
config.playlistTable,
|
|
86
|
+
)} as playlists
|
|
87
|
+
using (playlist_id)
|
|
88
|
+
|
|
89
|
+
`,
|
|
90
|
+
);
|
|
91
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by KEN-E, LLC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const column_descriptions = require("../column_descriptions");
|
|
6
|
+
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
return publish("ytc_playback", {
|
|
10
|
+
type: "incremental",
|
|
11
|
+
schema: config.datasetIntermediate,
|
|
12
|
+
tags: ["youtube", "output", "daily"],
|
|
13
|
+
bigquery: {
|
|
14
|
+
partitionBy: "interaction_date",
|
|
15
|
+
clusterBy: ["video_id", "playback_location_type"],
|
|
16
|
+
},
|
|
17
|
+
columns: column_descriptions.column_descriptions,
|
|
18
|
+
description: "YT Channel Playback Location Report Table - Intermediate",
|
|
19
|
+
})
|
|
20
|
+
.preOps(
|
|
21
|
+
(ctx) => `
|
|
22
|
+
declare interaction_date_checkpoint default (
|
|
23
|
+
select date("${config.startDate}")
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
--Set the incremental update checkpoint based on current max partition value minus lookback.
|
|
27
|
+
set interaction_date_checkpoint = (
|
|
28
|
+
${ctx.when(
|
|
29
|
+
ctx.incremental(),
|
|
30
|
+
`select
|
|
31
|
+
least(
|
|
32
|
+
(select date_sub(current_date(), interval ${config.daysBack} day)),
|
|
33
|
+
(select date_sub(max(interaction_date), interval ${config.daysBack} day) from ${ctx.self()})
|
|
34
|
+
)`,
|
|
35
|
+
`select date("${config.startDate}")`,
|
|
36
|
+
)}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
${ctx.when(
|
|
40
|
+
ctx.incremental(),
|
|
41
|
+
`delete ${ctx.self()} where interaction_date > interaction_date_checkpoint`,
|
|
42
|
+
)}
|
|
43
|
+
`,
|
|
44
|
+
)
|
|
45
|
+
.query(
|
|
46
|
+
(ctx) => `
|
|
47
|
+
|
|
48
|
+
-- determine max possible viewing seconds per row so that percent viewed can be calculated downstream
|
|
49
|
+
with int_ex_titles as (
|
|
50
|
+
select
|
|
51
|
+
* except (source_partition_date),
|
|
52
|
+
views * safe_divide(average_view_duration_seconds, average_view_duration_percentage) as row_max_duration_seconds
|
|
53
|
+
from ${ctx.ref("stg_ytc_playback")}
|
|
54
|
+
where interaction_date > interaction_date_checkpoint
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
select
|
|
58
|
+
int_ex_titles.*,
|
|
59
|
+
pl.playback_location_name,
|
|
60
|
+
ifnull(titles.video_title, int_ex_titles.video_id) as video_title
|
|
61
|
+
from int_ex_titles
|
|
62
|
+
left join ${ctx.ref("stg_ytc_lu_playback_location")} as pl
|
|
63
|
+
using (playback_location_type)
|
|
64
|
+
left join ${ctx.ref(
|
|
65
|
+
config.titlesProject,
|
|
66
|
+
config.titlesDataset,
|
|
67
|
+
config.titlesTable,
|
|
68
|
+
)} as titles
|
|
69
|
+
using (video_id)
|
|
70
|
+
|
|
71
|
+
`,
|
|
72
|
+
);
|
|
73
|
+
};
|