From 0c78e313004f1343cd8c76a303cfa691db8b7e7d Mon Sep 17 00:00:00 2001 From: Bas Broekhuizen Date: Tue, 8 Jul 2025 10:17:18 +0200 Subject: [PATCH 1/3] Add table view as alternative to donut chart for event properties --- .../events/EventProperties.module.css | 12 ++-- .../[websiteId]/events/EventProperties.tsx | 68 ++++++++++++++----- src/components/messages.ts | 2 + 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/events/EventProperties.module.css b/src/app/(main)/websites/[websiteId]/events/EventProperties.module.css index 0b9c011d..a56df28f 100644 --- a/src/app/(main)/websites/[websiteId]/events/EventProperties.module.css +++ b/src/app/(main)/websites/[websiteId]/events/EventProperties.module.css @@ -14,12 +14,14 @@ color: var(--primary400); } -.title { - text-align: center; - font-weight: bold; - margin: 20px 0; +.header { + margin-bottom: 40px; } -.chart { +.title { + font-weight: bold; +} + +.data { min-height: 620px; } diff --git a/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx b/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx index 453aa9a8..6d555e5d 100644 --- a/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx +++ b/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx @@ -1,7 +1,9 @@ -import { GridColumn, GridTable } from 'react-basics'; +import { useMemo } from 'react'; +import { GridColumn, GridTable, Flexbox, Button, ButtonGroup } from 'react-basics'; import { useEventDataProperties, useEventDataValues, useMessages } from '@/components/hooks'; import { LoadingPanel } from '@/components/common/LoadingPanel'; import PieChart from '@/components/charts/PieChart'; +import ListTable from '@/components/metrics/ListTable'; import { useState } from 'react'; import { CHART_COLORS } from '@/lib/constants'; import styles from './EventProperties.module.css'; @@ -9,22 +11,38 @@ import styles from './EventProperties.module.css'; export function EventProperties({ websiteId }: { websiteId: string }) { const [propertyName, setPropertyName] = useState(''); const [eventName, setEventName] = useState(''); + const [propertyView, setPropertyView] = useState('table'); + const { formatMessage, labels } = useMessages(); const { data, isLoading, isFetched, error } = useEventDataProperties(websiteId); const { data: values } = useEventDataValues(websiteId, eventName, propertyName); - const chartData = - propertyName && values - ? { - labels: values.map(({ value }) => value), - datasets: [ - { - data: values.map(({ total }) => total), - backgroundColor: CHART_COLORS, - borderWidth: 0, - }, - ], - } - : null; + + const propertySum = useMemo(() => { + return values?.reduce((sum, { total }) => sum + total, 0) ?? 0; + }, [values]); + + const chartData = useMemo(() => { + if (!propertyName || !values) return null; + return { + labels: values.map(({ value }) => value), + datasets: [ + { + data: values.map(({ total }) => total), + backgroundColor: CHART_COLORS, + borderWidth: 0, + }, + ], + }; + }, [propertyName, values]); + + const tableData = useMemo(() => { + if (!propertyName || !values || propertySum === 0) return []; + return values.map(({ value, total }) => ({ + x: value, + y: total, + z: 100 * (total / propertySum), + })); + }, [propertyName, values, propertySum]); const handleRowClick = row => { setEventName(row.eventName); @@ -52,9 +70,25 @@ export function EventProperties({ websiteId }: { websiteId: string }) { {propertyName && ( -
-
{propertyName}
- +
+ +
{`${eventName}: ${propertyName}`}
+ setPropertyView(key as string)} + > + + + +
+ + {values?.length === 0 ? ( +
{formatMessage(labels.noData)}
+ ) : propertyView === 'table' ? ( + + ) : ( + + )}
)}
diff --git a/src/components/messages.ts b/src/components/messages.ts index 19912b05..893bf141 100644 --- a/src/components/messages.ts +++ b/src/components/messages.ts @@ -310,6 +310,8 @@ export const labels = defineMessages({ paidVideo: { id: 'label.paid-video', defaultMessage: 'Paid video' }, grouped: { id: 'label.grouped', defaultMessage: 'Grouped' }, other: { id: 'label.other', defaultMessage: 'Other' }, + chart: { id: 'label.chart', defaultMessage: 'Chart' }, + table: { id: 'label.table', defaultMessage: 'Table' }, }); export const messages = defineMessages({ From 23120ec0115f03683fab97a061c324ae791cf1a7 Mon Sep 17 00:00:00 2001 From: Bas Broekhuizen Date: Wed, 9 Jul 2025 09:10:02 +0200 Subject: [PATCH 2/3] Replace loading text with icon --- .../(main)/websites/[websiteId]/events/EventProperties.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx b/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx index 6d555e5d..e3e442ad 100644 --- a/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx +++ b/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { GridColumn, GridTable, Flexbox, Button, ButtonGroup } from 'react-basics'; +import { GridColumn, GridTable, Flexbox, Button, ButtonGroup, Loading } from 'react-basics'; import { useEventDataProperties, useEventDataValues, useMessages } from '@/components/hooks'; import { LoadingPanel } from '@/components/common/LoadingPanel'; import PieChart from '@/components/charts/PieChart'; @@ -82,8 +82,8 @@ export function EventProperties({ websiteId }: { websiteId: string }) { - {values?.length === 0 ? ( -
{formatMessage(labels.noData)}
+ {!values ? ( + ) : propertyView === 'table' ? ( ) : ( From 2dcb9e21bdf9cc51fe500ad72562e4e9b5ae9b68 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Sun, 13 Jul 2025 22:44:09 -0700 Subject: [PATCH 3/3] change pagestable to visitors and update clickhouse hostname column to array --- .../migrations/08_update_hostname_view.sql | 253 ++++++++++++++++++ db/clickhouse/schema.sql | 8 +- src/components/metrics/PagesTable.tsx | 2 +- src/lib/constants.ts | 13 +- src/queries/sql/getValues.ts | 13 + .../sql/pageviews/getPageviewMetrics.ts | 19 +- src/queries/sql/sessions/getWebsiteSession.ts | 12 +- .../sql/sessions/getWebsiteSessions.ts | 5 +- 8 files changed, 296 insertions(+), 29 deletions(-) create mode 100644 db/clickhouse/migrations/08_update_hostname_view.sql diff --git a/db/clickhouse/migrations/08_update_hostname_view.sql b/db/clickhouse/migrations/08_update_hostname_view.sql new file mode 100644 index 00000000..061fa628 --- /dev/null +++ b/db/clickhouse/migrations/08_update_hostname_view.sql @@ -0,0 +1,253 @@ +-- create new hourly table +CREATE TABLE umami.website_event_stats_hourly_new +( + website_id UUID, + session_id UUID, + visit_id UUID, + hostname SimpleAggregateFunction(groupArrayArray, Array(String)), + browser LowCardinality(String), + os LowCardinality(String), + device LowCardinality(String), + screen LowCardinality(String), + language LowCardinality(String), + country LowCardinality(String), + region LowCardinality(String), + city String, + entry_url AggregateFunction(argMin, String, DateTime('UTC')), + exit_url AggregateFunction(argMax, String, DateTime('UTC')), + url_path SimpleAggregateFunction(groupArrayArray, Array(String)), + url_query SimpleAggregateFunction(groupArrayArray, Array(String)), + utm_source SimpleAggregateFunction(groupArrayArray, Array(String)), + utm_medium SimpleAggregateFunction(groupArrayArray, Array(String)), + utm_campaign SimpleAggregateFunction(groupArrayArray, Array(String)), + utm_content SimpleAggregateFunction(groupArrayArray, Array(String)), + utm_term SimpleAggregateFunction(groupArrayArray, Array(String)), + referrer_domain SimpleAggregateFunction(groupArrayArray, Array(String)), + page_title SimpleAggregateFunction(groupArrayArray, Array(String)), + gclid SimpleAggregateFunction(groupArrayArray, Array(String)), + fbclid SimpleAggregateFunction(groupArrayArray, Array(String)), + msclkid SimpleAggregateFunction(groupArrayArray, Array(String)), + ttclid SimpleAggregateFunction(groupArrayArray, Array(String)), + li_fat_id SimpleAggregateFunction(groupArrayArray, Array(String)), + twclid SimpleAggregateFunction(groupArrayArray, Array(String)), + event_type UInt32, + event_name SimpleAggregateFunction(groupArrayArray, Array(String)), + views SimpleAggregateFunction(sum, UInt64), + min_time SimpleAggregateFunction(min, DateTime('UTC')), + max_time SimpleAggregateFunction(max, DateTime('UTC')), + tag SimpleAggregateFunction(groupArrayArray, Array(String)), + distinct_id String, + created_at Datetime('UTC') +) +ENGINE = AggregatingMergeTree + PARTITION BY toYYYYMM(created_at) + ORDER BY ( + website_id, + event_type, + toStartOfHour(created_at), + cityHash64(visit_id), + visit_id + ) + SAMPLE BY cityHash64(visit_id); + +-- create view +CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv_new +TO umami.website_event_stats_hourly_new +AS +SELECT + website_id, + session_id, + visit_id, + hostnames as hostname, + browser, + os, + device, + screen, + language, + country, + region, + city, + entry_url, + exit_url, + url_paths as url_path, + url_query, + utm_source, + utm_medium, + utm_campaign, + utm_content, + utm_term, + referrer_domain, + page_title, + gclid, + fbclid, + msclkid, + ttclid, + li_fat_id, + twclid, + event_type, + event_name, + views, + min_time, + max_time, + tag, + distinct_id, + timestamp as created_at +FROM (SELECT + website_id, + session_id, + visit_id, + arrayFilter(x -> x != '', groupArray(hostname)) hostnames, + browser, + os, + device, + screen, + language, + country, + region, + city, + argMinState(url_path, created_at) entry_url, + argMaxState(url_path, created_at) exit_url, + arrayFilter(x -> x != '', groupArray(url_path)) as url_paths, + arrayFilter(x -> x != '', groupArray(url_query)) url_query, + arrayFilter(x -> x != '', groupArray(utm_source)) utm_source, + arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium, + arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign, + arrayFilter(x -> x != '', groupArray(utm_content)) utm_content, + arrayFilter(x -> x != '', groupArray(utm_term)) utm_term, + arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain, + arrayFilter(x -> x != '', groupArray(page_title)) page_title, + arrayFilter(x -> x != '', groupArray(gclid)) gclid, + arrayFilter(x -> x != '', groupArray(fbclid)) fbclid, + arrayFilter(x -> x != '', groupArray(msclkid)) msclkid, + arrayFilter(x -> x != '', groupArray(ttclid)) ttclid, + arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id, + arrayFilter(x -> x != '', groupArray(twclid)) twclid, + event_type, + if(event_type = 2, groupArray(event_name), []) event_name, + sumIf(1, event_type = 1) views, + min(created_at) min_time, + max(created_at) max_time, + arrayFilter(x -> x != '', groupArray(tag)) tag, + distinct_id, + toStartOfHour(created_at) timestamp +FROM umami.website_event +GROUP BY website_id, + session_id, + visit_id, + hostname, + browser, + os, + device, + screen, + language, + country, + region, + city, + event_type, + distinct_id, + timestamp); + +-- rename tables +RENAME TABLE umami.website_event_stats_hourly TO umami.website_event_stats_hourly_old; +RENAME TABLE umami.website_event_stats_hourly_new TO umami.website_event_stats_hourly; + +-- drop views +DROP TABLE umami.website_event_stats_hourly_mv; +DROP TABLE umami.website_event_stats_hourly_mv_new; + +-- recreate view +CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv +TO umami.website_event_stats_hourly +AS +SELECT + website_id, + session_id, + visit_id, + hostnames as hostname, + browser, + os, + device, + screen, + language, + country, + region, + city, + entry_url, + exit_url, + url_paths as url_path, + url_query, + utm_source, + utm_medium, + utm_campaign, + utm_content, + utm_term, + referrer_domain, + page_title, + gclid, + fbclid, + msclkid, + ttclid, + li_fat_id, + twclid, + event_type, + event_name, + views, + min_time, + max_time, + tag, + distinct_id, + timestamp as created_at +FROM (SELECT + website_id, + session_id, + visit_id, + arrayFilter(x -> x != '', groupArray(hostname)) hostnames, + browser, + os, + device, + screen, + language, + country, + region, + city, + argMinState(url_path, created_at) entry_url, + argMaxState(url_path, created_at) exit_url, + arrayFilter(x -> x != '', groupArray(url_path)) as url_paths, + arrayFilter(x -> x != '', groupArray(url_query)) url_query, + arrayFilter(x -> x != '', groupArray(utm_source)) utm_source, + arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium, + arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign, + arrayFilter(x -> x != '', groupArray(utm_content)) utm_content, + arrayFilter(x -> x != '', groupArray(utm_term)) utm_term, + arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain, + arrayFilter(x -> x != '', groupArray(page_title)) page_title, + arrayFilter(x -> x != '', groupArray(gclid)) gclid, + arrayFilter(x -> x != '', groupArray(fbclid)) fbclid, + arrayFilter(x -> x != '', groupArray(msclkid)) msclkid, + arrayFilter(x -> x != '', groupArray(ttclid)) ttclid, + arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id, + arrayFilter(x -> x != '', groupArray(twclid)) twclid, + event_type, + if(event_type = 2, groupArray(event_name), []) event_name, + sumIf(1, event_type = 1) views, + min(created_at) min_time, + max(created_at) max_time, + arrayFilter(x -> x != '', groupArray(tag)) tag, + distinct_id, + toStartOfHour(created_at) timestamp +FROM umami.website_event +GROUP BY website_id, + session_id, + visit_id, + hostname, + browser, + os, + device, + screen, + language, + country, + region, + city, + event_type, + distinct_id, + timestamp); diff --git a/db/clickhouse/schema.sql b/db/clickhouse/schema.sql index d9831f57..41b3a1b3 100644 --- a/db/clickhouse/schema.sql +++ b/db/clickhouse/schema.sql @@ -90,7 +90,7 @@ CREATE TABLE umami.website_event_stats_hourly website_id UUID, session_id UUID, visit_id UUID, - hostname LowCardinality(String), + hostname SimpleAggregateFunction(groupArrayArray, Array(String)), browser LowCardinality(String), os LowCardinality(String), device LowCardinality(String), @@ -143,7 +143,7 @@ SELECT website_id, session_id, visit_id, - hostname, + hostnames as hostname, browser, os, device, @@ -181,7 +181,7 @@ FROM (SELECT website_id, session_id, visit_id, - hostname, + arrayFilter(x -> x != '', groupArray(hostname)) hostnames, browser, os, device, @@ -199,7 +199,7 @@ FROM (SELECT arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign, arrayFilter(x -> x != '', groupArray(utm_content)) utm_content, arrayFilter(x -> x != '', groupArray(utm_term)) utm_term, - arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain, + arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain, arrayFilter(x -> x != '', groupArray(page_title)) page_title, arrayFilter(x -> x != '', groupArray(gclid)) gclid, arrayFilter(x -> x != '', groupArray(fbclid)) fbclid, diff --git a/src/components/metrics/PagesTable.tsx b/src/components/metrics/PagesTable.tsx index 8163b3d9..59cfda43 100644 --- a/src/components/metrics/PagesTable.tsx +++ b/src/components/metrics/PagesTable.tsx @@ -62,7 +62,7 @@ export function PagesTable({ allowFilter, ...props }: PagesTableProps) { {...props} title={formatMessage(labels.pages)} type={view} - metric={formatMessage(labels.views)} + metric={formatMessage(labels.visitors)} dataFilter={emptyFilter} renderLabel={renderLink} > diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 39ecbc08..7fd1a85d 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -33,7 +33,17 @@ export const FILTER_REFERRERS = 'filter-referrers'; export const FILTER_PAGES = 'filter-pages'; export const UNIT_TYPES = ['year', 'month', 'hour', 'day', 'minute']; -export const EVENT_COLUMNS = ['url', 'entry', 'exit', 'referrer', 'title', 'query', 'event', 'tag']; +export const EVENT_COLUMNS = [ + 'url', + 'entry', + 'exit', + 'referrer', + 'title', + 'query', + 'event', + 'tag', + 'host', +]; export const SESSION_COLUMNS = [ 'browser', @@ -44,7 +54,6 @@ export const SESSION_COLUMNS = [ 'country', 'city', 'region', - 'host', ]; export const FILTER_GROUPS = { diff --git a/src/queries/sql/getValues.ts b/src/queries/sql/getValues.ts index 2d1286f3..5322a531 100644 --- a/src/queries/sql/getValues.ts +++ b/src/queries/sql/getValues.ts @@ -21,6 +21,12 @@ async function relationalQuery( const { rawQuery, getSearchSQL } = prisma; const params = {}; let searchQuery = ''; + let excludeDomain = ''; + + if (column === 'referrer_domain') { + excludeDomain = `and website_event.referrer_domain != website_event.hostname + and website_event.referrer_domain != ''`; + } if (search) { if (decodeURIComponent(search).includes(',')) { @@ -49,6 +55,7 @@ async function relationalQuery( where website_event.website_id = {{websiteId::uuid}} and website_event.created_at between {{startDate}} and {{endDate}} ${searchQuery} + ${excludeDomain} group by 1 order by 2 desc limit 10 @@ -73,6 +80,11 @@ async function clickhouseQuery( const { rawQuery, getSearchSQL } = clickhouse; const params = {}; let searchQuery = ''; + let excludeDomain = ''; + + if (column === 'referrer_domain') { + excludeDomain = `and referrer_domain != hostname and referrer_domain != ''`; + } if (search) { searchQuery = `and positionCaseInsensitive(${column}, {search:String}) > 0`; @@ -103,6 +115,7 @@ async function clickhouseQuery( where website_id = {websiteId:UUID} and created_at between {startDate:DateTime64} and {endDate:DateTime64} ${searchQuery} + ${excludeDomain} group by 1 order by 2 desc limit 10 diff --git a/src/queries/sql/pageviews/getPageviewMetrics.ts b/src/queries/sql/pageviews/getPageviewMetrics.ts index 72586eb7..67e18b75 100644 --- a/src/queries/sql/pageviews/getPageviewMetrics.ts +++ b/src/queries/sql/pageviews/getPageviewMetrics.ts @@ -34,7 +34,7 @@ async function relationalQuery( ...filters, eventType: column === 'event_name' ? EVENT_TYPE.customEvent : EVENT_TYPE.pageView, }, - { joinSession: SESSION_COLUMNS.includes(type) || column === 'referrer_domain' }, + { joinSession: SESSION_COLUMNS.includes(type) }, ); let entryExitQuery = ''; @@ -66,7 +66,7 @@ async function relationalQuery( return rawQuery( ` select ${column} x, - ${column === 'referrer_domain' ? 'count(distinct website_event.session_id)' : 'count(*)'} as y + count(distinct website_event.session_id) as y from website_event ${cohortQuery} ${joinSession} @@ -126,7 +126,7 @@ async function clickhouseQuery( sql = ` select ${column} x, - ${column === 'referrer_domain' ? 'uniq(session_id)' : 'count(*)'} as y + uniq(website_event.session_id) as y from website_event ${cohortQuery} ${entryExitQuery} @@ -142,28 +142,27 @@ async function clickhouseQuery( `; } else { let groupByQuery = ''; - let columnQuery = `arrayJoin(${column})`; + let columnQuery = `session_id s, arrayJoin(${column})`; if (column === 'referrer_domain') { - excludeDomain = `and t != hostname and t != ''`; - columnQuery = `session_id s, arrayJoin(${column})`; + excludeDomain = `and t != ''`; } if (type === 'entry') { - columnQuery = `visit_id x, argMinMerge(entry_url)`; + columnQuery = `session_id s, argMinMerge(entry_url)`; } if (type === 'exit') { - columnQuery = `visit_id x, argMaxMerge(exit_url)`; + columnQuery = `session_id s, argMaxMerge(exit_url)`; } if (type === 'entry' || type === 'exit') { - groupByQuery = 'group by x'; + groupByQuery = 'group by s'; } sql = ` select g.t as x, - ${column === 'referrer_domain' ? 'uniq(s)' : 'count(*)'} as y + uniq(s) as y from ( select ${columnQuery} as t from website_event_stats_hourly website_event diff --git a/src/queries/sql/sessions/getWebsiteSession.ts b/src/queries/sql/sessions/getWebsiteSession.ts index 97850a2c..8c549ca3 100644 --- a/src/queries/sql/sessions/getWebsiteSession.ts +++ b/src/queries/sql/sessions/getWebsiteSession.ts @@ -17,7 +17,6 @@ async function relationalQuery(websiteId: string, sessionId: string) { select id, distinct_id as "distinctId", website_id as "websiteId", - hostname, browser, os, device, @@ -37,7 +36,6 @@ async function relationalQuery(websiteId: string, sessionId: string) { session.distinct_id, website_event.visit_id, session.website_id, - website_event.hostname, session.browser, session.os, session.device, @@ -54,8 +52,8 @@ async function relationalQuery(websiteId: string, sessionId: string) { join website_event on website_event.session_id = session.session_id where session.website_id = {{websiteId::uuid}} and session.session_id = {{sessionId::uuid}} - group by session.session_id, session.distinct_id, visit_id, session.website_id, website_event.hostname, session.browser, session.os, session.device, session.screen, session.language, session.country, session.region, session.city) t - group by id, distinct_id, website_id, hostname, browser, os, device, screen, language, country, region, city; + group by session.session_id, session.distinct_id, visit_id, session.website_id, session.browser, session.os, session.device, session.screen, session.language, session.country, session.region, session.city) t + group by id, distinct_id, website_id, browser, os, device, screen, language, country, region, city; `, { websiteId, sessionId }, ).then(result => result?.[0]); @@ -69,7 +67,6 @@ async function clickhouseQuery(websiteId: string, sessionId: string) { select id, websiteId, distinctId, - hostname, browser, os, device, @@ -89,7 +86,6 @@ async function clickhouseQuery(websiteId: string, sessionId: string) { distinct_id as distinctId, visit_id, website_id as websiteId, - hostname, browser, os, device, @@ -105,8 +101,8 @@ async function clickhouseQuery(websiteId: string, sessionId: string) { from website_event_stats_hourly where website_id = {websiteId:UUID} and session_id = {sessionId:UUID} - group by session_id, distinct_id, visit_id, website_id, hostname, browser, os, device, screen, language, country, region, city) t - group by id, websiteId, distinctId, hostname, browser, os, device, screen, language, country, region, city; + group by session_id, distinct_id, visit_id, website_id, browser, os, device, screen, language, country, region, city) t + group by id, websiteId, distinctId, browser, os, device, screen, language, country, region, city; `, { websiteId, sessionId }, ).then(result => result?.[0]); diff --git a/src/queries/sql/sessions/getWebsiteSessions.ts b/src/queries/sql/sessions/getWebsiteSessions.ts index 8f99df2d..6171e514 100644 --- a/src/queries/sql/sessions/getWebsiteSessions.ts +++ b/src/queries/sql/sessions/getWebsiteSessions.ts @@ -27,7 +27,6 @@ async function relationalQuery(websiteId: string, filters: QueryFilters, pagePar select session.session_id as "id", session.website_id as "websiteId", - website_event.hostname, session.browser, session.os, session.device, @@ -58,7 +57,6 @@ async function relationalQuery(websiteId: string, filters: QueryFilters, pagePar } group by session.session_id, session.website_id, - website_event.hostname, session.browser, session.os, session.device, @@ -84,7 +82,6 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters, pagePar select session_id as id, website_id as websiteId, - hostname, browser, os, device, @@ -112,7 +109,7 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters, pagePar or (positionCaseInsensitive(device, {search:String}) > 0))` : '' } - group by session_id, website_id, hostname, browser, os, device, screen, language, country, region, city + group by session_id, website_id, browser, os, device, screen, language, country, region, city order by lastAt desc `, { ...params, search },