chore: update SQL tools
Browse files- SQL/Formula1_Data_Analysis_Views.sqlite3-query +0 -120
- SQL/schema.sqlite3-query +0 -105
- tools/sql/driver_performance.query.sql +23 -0
- tools/sql/event_performance.query.sql +18 -0
- tools/{telemetry_and_weather_query.sql → sql/telemetry_analysis.query.sql} +0 -0
- tools/sql/tyre_performance.query.sql +16 -0
- tools/sql/weather_impact.query.sql +18 -0
SQL/Formula1_Data_Analysis_Views.sqlite3-query
DELETED
@@ -1,120 +0,0 @@
|
|
1 |
-
-- 1. Driver Performance Summary with Weather
|
2 |
-
CREATE VIEW DriverPerformanceSummaryWithWeather AS
|
3 |
-
SELECT
|
4 |
-
l.driver_name,
|
5 |
-
e.event_name,
|
6 |
-
s.session_type,
|
7 |
-
t.track_name,
|
8 |
-
COUNT(l.lap_id) AS total_laps,
|
9 |
-
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
10 |
-
MIN(l.lap_time_in_seconds) AS best_lap_time,
|
11 |
-
AVG(l.sector_1_time_in_seconds) AS avg_sector1_time,
|
12 |
-
AVG(l.sector_2_time_in_seconds) AS avg_sector2_time,
|
13 |
-
AVG(l.sector_3_time_in_seconds) AS avg_sector3_time,
|
14 |
-
AVG(l.finish_line_speed_trap_in_km) AS avg_finish_line_speed,
|
15 |
-
COUNT(CASE WHEN l.is_personal_best THEN 1 END) AS personal_best_laps,
|
16 |
-
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
17 |
-
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
18 |
-
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage
|
19 |
-
FROM Laps l
|
20 |
-
JOIN Sessions s ON l.session_id = s.session_id
|
21 |
-
JOIN Tracks t ON s.track_id = t.track_id
|
22 |
-
JOIN Event e ON s.event_id = e.event_id
|
23 |
-
LEFT JOIN Weather w ON s.session_id = w.session_id
|
24 |
-
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
25 |
-
GROUP BY l.driver_name, e.event_id, s.session_id;
|
26 |
-
|
27 |
-
-- 2. Tyre Performance Analysis with Weather
|
28 |
-
CREATE VIEW TyrePerformanceAnalysisWithWeather AS
|
29 |
-
SELECT
|
30 |
-
l.driver_name,
|
31 |
-
e.event_name,
|
32 |
-
s.session_type,
|
33 |
-
t.track_name,
|
34 |
-
l.tyre_compound,
|
35 |
-
AVG(l.tyre_life_in_laps) AS avg_tyre_life,
|
36 |
-
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
37 |
-
AVG(l.longest_strait_speed_trap_in_km) AS avg_top_speed,
|
38 |
-
COUNT(CASE WHEN l.is_fresh_tyre THEN 1 END) AS fresh_tyre_laps,
|
39 |
-
COUNT(CASE WHEN NOT l.is_fresh_tyre THEN 1 END) AS used_tyre_laps,
|
40 |
-
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
41 |
-
AVG(w.air_temperature_in_celsius) AS avg_air_temp
|
42 |
-
FROM Laps l
|
43 |
-
JOIN Sessions s ON l.session_id = s.session_id
|
44 |
-
JOIN Tracks t ON s.track_id = t.track_id
|
45 |
-
JOIN Event e ON s.event_id = e.event_id
|
46 |
-
LEFT JOIN Weather w ON s.session_id = w.session_id
|
47 |
-
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
48 |
-
GROUP BY l.driver_name, e.event_id, s.session_id, l.tyre_compound;
|
49 |
-
|
50 |
-
-- 3. Weather Impact Analysis
|
51 |
-
CREATE VIEW WeatherImpactAnalysis AS
|
52 |
-
SELECT
|
53 |
-
e.event_name,
|
54 |
-
s.session_type,
|
55 |
-
t.track_name,
|
56 |
-
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
57 |
-
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
58 |
-
AVG(w.relative_air_humidity_in_percentage) AS avg_humidity,
|
59 |
-
AVG(w.wind_speed_in_meters_per_seconds) AS avg_wind_speed,
|
60 |
-
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage,
|
61 |
-
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
62 |
-
MIN(l.lap_time_in_seconds) AS best_lap_time
|
63 |
-
FROM Weather w
|
64 |
-
JOIN Sessions s ON w.session_id = s.session_id
|
65 |
-
JOIN Tracks t ON s.track_id = t.track_id
|
66 |
-
JOIN Event e ON s.event_id = e.event_id
|
67 |
-
JOIN Laps l ON s.session_id = l.session_id
|
68 |
-
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
69 |
-
GROUP BY e.event_id, s.session_id;
|
70 |
-
|
71 |
-
-- 4. Event Performance Overview
|
72 |
-
CREATE VIEW EventPerformanceOverview AS
|
73 |
-
SELECT
|
74 |
-
e.event_name,
|
75 |
-
e.country,
|
76 |
-
e.location,
|
77 |
-
s.session_type,
|
78 |
-
COUNT(DISTINCT l.driver_name) AS driver_count,
|
79 |
-
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
80 |
-
MIN(l.lap_time_in_seconds) AS best_lap_time,
|
81 |
-
MAX(l.finish_line_speed_trap_in_km) AS max_finish_line_speed,
|
82 |
-
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
83 |
-
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
84 |
-
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage
|
85 |
-
FROM Event e
|
86 |
-
JOIN Sessions s ON e.event_id = s.event_id
|
87 |
-
JOIN Laps l ON s.session_id = l.session_id
|
88 |
-
LEFT JOIN Weather w ON s.session_id = w.session_id
|
89 |
-
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
90 |
-
GROUP BY e.event_id, s.session_id;
|
91 |
-
|
92 |
-
-- 5. Telemetry Analysis with Weather
|
93 |
-
CREATE VIEW TelemetryAnalysisWithWeather AS
|
94 |
-
SELECT
|
95 |
-
l.lap_id,
|
96 |
-
l.driver_name,
|
97 |
-
e.event_name,
|
98 |
-
s.session_type,
|
99 |
-
t.track_name,
|
100 |
-
l.lap_number,
|
101 |
-
l.lap_time_in_seconds,
|
102 |
-
AVG(tel.speed_in_km) AS avg_speed,
|
103 |
-
MAX(tel.speed_in_km) AS max_speed,
|
104 |
-
AVG(tel.RPM) AS avg_RPM,
|
105 |
-
MAX(tel.RPM) AS max_RPM,
|
106 |
-
AVG(tel.throttle_input) AS avg_throttle,
|
107 |
-
SUM(CASE WHEN tel.is_brake_pressed THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS brake_percentage,
|
108 |
-
SUM(CASE WHEN tel.is_DRS_open THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS drs_usage_percentage,
|
109 |
-
SUM(CASE WHEN tel.is_off_track THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS off_track_percentage,
|
110 |
-
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
111 |
-
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
112 |
-
AVG(w.wind_speed_in_meters_per_seconds) AS avg_wind_speed
|
113 |
-
FROM Laps l
|
114 |
-
JOIN Sessions s ON l.session_id = s.session_id
|
115 |
-
JOIN Tracks t ON s.track_id = t.track_id
|
116 |
-
JOIN Event e ON s.event_id = e.event_id
|
117 |
-
JOIN Telemetry tel ON l.lap_id = tel.lap_id
|
118 |
-
LEFT JOIN Weather w ON s.session_id = w.session_id
|
119 |
-
AND tel.datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
120 |
-
GROUP BY l.lap_id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQL/schema.sqlite3-query
DELETED
@@ -1,105 +0,0 @@
|
|
1 |
-
CREATE TABLE Drivers (
|
2 |
-
driver_id INTEGER PRIMARY KEY,
|
3 |
-
driver_name TEXT NOT NULL,
|
4 |
-
team TEXT NOT NULL
|
5 |
-
);
|
6 |
-
|
7 |
-
CREATE TABLE Tracks (
|
8 |
-
track_id INTEGER PRIMARY KEY,
|
9 |
-
track_name TEXT NOT NULL,
|
10 |
-
country TEXT NOT NULL
|
11 |
-
);
|
12 |
-
|
13 |
-
CREATE TABLE Event (
|
14 |
-
event_id INTEGER PRIMARY KEY,
|
15 |
-
round_number INTEGER,
|
16 |
-
country TEXT,
|
17 |
-
location TEXT,
|
18 |
-
event_date DATE,
|
19 |
-
event_name TEXT,
|
20 |
-
session_1_date_utc DATETIME,
|
21 |
-
session_1_name TEXT CHECK(session_1_name IN ('practice', 'qualify', 'race')),
|
22 |
-
session_2_date_utc DATETIME,
|
23 |
-
session_2_name TEXT CHECK(session_2_name IN ('practice', 'qualify', 'race')),
|
24 |
-
session_3_date_utc DATETIME,
|
25 |
-
session_3_name TEXT CHECK(session_3_name IN ('practice', 'qualify', 'race')),
|
26 |
-
session_4_date_utc DATETIME,
|
27 |
-
session_4_name TEXT CHECK(session_4_name IN ('practice', 'qualify', 'race')),
|
28 |
-
session_5_date_utc DATETIME,
|
29 |
-
session_5_name TEXT CHECK(session_5_name IN ('practice', 'qualify', 'race'))
|
30 |
-
);
|
31 |
-
|
32 |
-
CREATE TABLE Sessions (
|
33 |
-
session_id INTEGER PRIMARY KEY,
|
34 |
-
event_id INTEGER,
|
35 |
-
track_id INTEGER,
|
36 |
-
session_type TEXT NOT NULL,
|
37 |
-
date TEXT NOT NULL,
|
38 |
-
FOREIGN KEY (event_id) REFERENCES Event(event_id),
|
39 |
-
FOREIGN KEY (track_id) REFERENCES Tracks(track_id)
|
40 |
-
);
|
41 |
-
|
42 |
-
CREATE TABLE Weather (
|
43 |
-
weather_id INTEGER PRIMARY KEY,
|
44 |
-
session_id INTEGER,
|
45 |
-
datetime DATETIME,
|
46 |
-
air_temperature_in_celsius REAL,
|
47 |
-
relative_air_humidity_in_percentage REAL,
|
48 |
-
air_pressure_in_mbar REAL,
|
49 |
-
is_raining BOOLEAN,
|
50 |
-
track_temperature_in_celsius REAL,
|
51 |
-
wind_direction_in_grads REAL,
|
52 |
-
wind_speed_in_meters_per_seconds REAL,
|
53 |
-
FOREIGN KEY (session_id) REFERENCES Sessions(session_id)
|
54 |
-
);
|
55 |
-
|
56 |
-
CREATE TABLE Laps (
|
57 |
-
lap_id INTEGER PRIMARY KEY,
|
58 |
-
session_id INTEGER,
|
59 |
-
driver_name TEXT NOT NULL,
|
60 |
-
lap_number INTEGER NOT NULL,
|
61 |
-
stint INTEGER,
|
62 |
-
sector_1_speed_trap_in_km REAL,
|
63 |
-
sector_2_speed_trap_in_km REAL,
|
64 |
-
finish_line_speed_trap_in_km REAL,
|
65 |
-
longest_strait_speed_trap_in_km REAL,
|
66 |
-
is_personal_best BOOLEAN,
|
67 |
-
tyre_compound TEXT,
|
68 |
-
tyre_life_in_laps INTEGER,
|
69 |
-
is_fresh_tyre BOOLEAN,
|
70 |
-
position INTEGER,
|
71 |
-
lap_time_in_seconds REAL,
|
72 |
-
sector_1_time_in_seconds REAL,
|
73 |
-
sector_2_time_in_seconds REAL,
|
74 |
-
sector_3_time_in_seconds REAL,
|
75 |
-
lap_start_time_in_datetime DATETIME,
|
76 |
-
pin_in_time_in_datetime DATETIME,
|
77 |
-
pin_out_time_in_datetime DATETIME,
|
78 |
-
FOREIGN KEY (session_id) REFERENCES Sessions(session_id),
|
79 |
-
UNIQUE (session_id, driver_name, lap_number)
|
80 |
-
);
|
81 |
-
|
82 |
-
CREATE TABLE Telemetry (
|
83 |
-
telemetry_id INTEGER PRIMARY KEY,
|
84 |
-
lap_id INTEGER,
|
85 |
-
speed_in_km REAL,
|
86 |
-
RPM INTEGER,
|
87 |
-
gear_number INTEGER,
|
88 |
-
throttle_input REAL CHECK (throttle_input BETWEEN 0 AND 100),
|
89 |
-
is_brake_pressed BOOLEAN,
|
90 |
-
is_DRS_open BOOLEAN,
|
91 |
-
x_position REAL,
|
92 |
-
y_position REAL,
|
93 |
-
z_position REAL,
|
94 |
-
is_off_track BOOLEAN,
|
95 |
-
datetime DATETIME,
|
96 |
-
FOREIGN KEY (lap_id) REFERENCES Laps(lap_id)
|
97 |
-
);
|
98 |
-
|
99 |
-
CREATE INDEX idx_laps_driver_name ON Laps(driver_name);
|
100 |
-
CREATE INDEX idx_laps_session_id ON Laps(session_id);
|
101 |
-
CREATE INDEX idx_telemetry_lap_id ON Telemetry(lap_id);
|
102 |
-
CREATE INDEX idx_telemetry_datetime ON Telemetry(datetime);
|
103 |
-
CREATE INDEX idx_weather_session_id ON Weather(session_id);
|
104 |
-
CREATE INDEX idx_weather_datetime ON Weather(datetime);
|
105 |
-
CREATE INDEX idx_event_date ON Event(event_date);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tools/sql/driver_performance.query.sql
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
SELECT
|
2 |
+
l.driver_name,
|
3 |
+
e.event_name,
|
4 |
+
s.session_type,
|
5 |
+
t.track_name,
|
6 |
+
COUNT(l.lap_id) AS total_laps,
|
7 |
+
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
8 |
+
MIN(l.lap_time_in_seconds) AS best_lap_time,
|
9 |
+
AVG(l.sector_1_time_in_seconds) AS avg_sector1_time,
|
10 |
+
AVG(l.sector_2_time_in_seconds) AS avg_sector2_time,
|
11 |
+
AVG(l.sector_3_time_in_seconds) AS avg_sector3_time,
|
12 |
+
AVG(l.finish_line_speed_trap_in_km) AS avg_finish_line_speed,
|
13 |
+
COUNT(CASE WHEN l.is_personal_best THEN 1 END) AS personal_best_laps,
|
14 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
15 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
16 |
+
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage
|
17 |
+
FROM Laps l
|
18 |
+
JOIN Sessions s ON l.session_id = s.session_id
|
19 |
+
JOIN Tracks t ON s.track_id = t.track_id
|
20 |
+
JOIN Event e ON s.event_id = e.event_id
|
21 |
+
LEFT JOIN Weather w ON s.session_id = w.session_id
|
22 |
+
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+1 minutes')
|
23 |
+
GROUP BY l.driver_name, e.event_id, s.session_id;
|
tools/sql/event_performance.query.sql
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
SELECT
|
2 |
+
e.event_name,
|
3 |
+
e.country,
|
4 |
+
e.location,
|
5 |
+
s.session_type,
|
6 |
+
COUNT(DISTINCT l.driver_name) AS driver_count,
|
7 |
+
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
8 |
+
MIN(l.lap_time_in_seconds) AS best_lap_time,
|
9 |
+
MAX(l.finish_line_speed_trap_in_km) AS max_finish_line_speed,
|
10 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
11 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
12 |
+
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage
|
13 |
+
FROM Event e
|
14 |
+
JOIN Sessions s ON e.event_id = s.event_id
|
15 |
+
JOIN Laps l ON s.session_id = l.session_id
|
16 |
+
LEFT JOIN Weather w ON s.session_id = w.session_id
|
17 |
+
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+1 minutes')
|
18 |
+
GROUP BY e.event_id, s.session_id;
|
tools/{telemetry_and_weather_query.sql → sql/telemetry_analysis.query.sql}
RENAMED
File without changes
|
tools/sql/tyre_performance.query.sql
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
SELECT
|
2 |
+
l.driver_name,
|
3 |
+
l.lap_number,
|
4 |
+
l.tyre_compound,
|
5 |
+
AVG(l.tyre_life_in_laps) AS avg_tyre_life,
|
6 |
+
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
7 |
+
AVG(l.longest_strait_speed_trap_in_km) AS avg_top_speed,
|
8 |
+
COUNT(CASE WHEN l.is_fresh_tyre THEN 1 END) AS fresh_tyre_laps,
|
9 |
+
COUNT(CASE WHEN NOT l.is_fresh_tyre THEN 1 END) AS used_tyre_laps,
|
10 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
11 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp
|
12 |
+
FROM Laps l
|
13 |
+
INNER JOIN Weather w ON l.session_id = w.session_id
|
14 |
+
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
15 |
+
WHERE l.driver_name = :driver_name
|
16 |
+
GROUP BY l.driver_name, l.lap_number, l.tyre_compound;
|
tools/sql/weather_impact.query.sql
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
SELECT
|
2 |
+
e.event_name,
|
3 |
+
s.session_type,
|
4 |
+
t.track_name,
|
5 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
6 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
7 |
+
AVG(w.relative_air_humidity_in_percentage) AS avg_humidity,
|
8 |
+
AVG(w.wind_speed_in_meters_per_seconds) AS avg_wind_speed,
|
9 |
+
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage,
|
10 |
+
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
11 |
+
MIN(l.lap_time_in_seconds) AS best_lap_time
|
12 |
+
FROM Weather w
|
13 |
+
JOIN Sessions s ON w.session_id = s.session_id
|
14 |
+
JOIN Tracks t ON s.track_id = t.track_id
|
15 |
+
JOIN Event e ON s.event_id = e.event_id
|
16 |
+
JOIN Laps l ON s.session_id = l.session_id
|
17 |
+
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+1 minutes')
|
18 |
+
GROUP BY e.event_id, s.session_id;
|