diff --git a/public/intl/messages/en-US.json b/public/intl/messages/en-US.json
index 38a7460d3..6614c6500 100644
--- a/public/intl/messages/en-US.json
+++ b/public/intl/messages/en-US.json
@@ -126,6 +126,7 @@
"filter-raw": "Raw",
"filters": "Filters",
"property-filter": "Property Filter",
+ "activity-by-property": "Activity by property",
"first-click": "First click",
"first-seen": "First seen",
"funnel": "Funnel",
diff --git a/src/app/(main)/websites/[websiteId]/session-data/HighCardinalityPropertyChart.tsx b/src/app/(main)/websites/[websiteId]/session-data/HighCardinalityPropertyChart.tsx
deleted file mode 100644
index 1dd39d757..000000000
--- a/src/app/(main)/websites/[websiteId]/session-data/HighCardinalityPropertyChart.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-'use client';
-import { PieChart } from '@/components/charts/PieChart';
-import { Empty } from '@/components/common/Empty';
-import { useMessages, useMobile } from '@/components/hooks';
-import { ListTable } from '@/components/metrics/ListTable';
-import { CHART_COLORS } from '@/lib/constants';
-import { formatLongNumber, formatShortTime } from '@/lib/format';
-import type { PropertyLeaderboardRow } from '@/lib/types';
-import { Column, DataColumn, DataTable, Grid, Row, Text } from '@umami/react-zen';
-import { useMemo } from 'react';
-
-export function HighCardinalityPropertyChart({ rows }: { rows: PropertyLeaderboardRow[] }) {
- const { t, labels } = useMessages();
- const { isPhone } = useMobile();
- const activeTable = useMemo(() => rows.filter(row => row.activity > 0).slice(0, 10), [rows]);
- const userMix = useMemo(() => {
- const totalNew = rows.reduce((sum, row) => sum + row.newSessions, 0);
- const totalReturning = rows.reduce((sum, row) => sum + row.returningSessions, 0);
- const total = totalNew + totalReturning;
-
- return {
- newCount: totalNew,
- returningCount: totalReturning,
- newRate: total ? (totalNew / total) * 100 : 0,
- returningRate: total ? (totalReturning / total) * 100 : 0,
- };
- }, [rows]);
- const sessionTypeTable = useMemo(() => {
- return [
- {
- label: 'New',
- count: userMix.newCount,
- percent: userMix.newRate,
- },
- {
- label: 'Returning',
- count: userMix.returningCount,
- percent: userMix.returningRate,
- },
- ].filter(row => row.count > 0);
- }, [userMix]);
- const sessionTypeChartData = useMemo(() => {
- if (!sessionTypeTable.length) return null;
-
- return {
- labels: sessionTypeTable.map(row => row.label),
- datasets: [
- {
- data: sessionTypeTable.map(row => row.count),
- backgroundColor: [CHART_COLORS[0], CHART_COLORS[1]],
- borderWidth: 0,
- },
- ],
- };
- }, [sessionTypeTable]);
-
- return (
-
-
-
-
- {activeTable.length === 0 ? (
-
- ) : isPhone ? (
-
-
-
- {row => (
-
-
- {row.label}
-
-
- )}
-
-
-
- ) : (
-
-
-
-
- {row => (
-
-
- {row.label}
-
-
- )}
-
-
- {row => formatLongNumber(row.sessions)}
-
-
- {row => formatLongNumber(row.visits)}
-
-
- {row => formatLongNumber(row.views)}
-
-
- {row => formatLongNumber(row.events)}
-
-
- {row =>
- formatShortTime(Math.abs(~~Number(row.totaltime)), ['h', 'm', 's'], ' ')
- }
-
-
-
-
- )}
-
-
-
-
-
-
- {sessionTypeChartData && }
-
-
-
- );
-}
diff --git a/src/app/(main)/websites/[websiteId]/session-data/SessionPropertyChart.tsx b/src/app/(main)/websites/[websiteId]/session-data/SessionPropertyChart.tsx
new file mode 100644
index 000000000..b175908df
--- /dev/null
+++ b/src/app/(main)/websites/[websiteId]/session-data/SessionPropertyChart.tsx
@@ -0,0 +1,136 @@
+'use client';
+import { DistributionBarChart } from '@/components/charts/DistributionBarChart';
+import { Empty } from '@/components/common/Empty';
+import { LoadingPanel } from '@/components/common/LoadingPanel';
+import { useMessages, useMobile, useSessionDataActivityStatsQuery } from '@/components/hooks';
+import { formatLongNumber, formatShortTime } from '@/lib/format';
+import type { PropertyFilter } from '@/lib/types';
+import { Column, DataColumn, DataTable, Grid, Row, Text } from '@umami/react-zen';
+import { useMemo } from 'react';
+
+export function SessionPropertyChart({
+ websiteId,
+ propertyName,
+ propertyFilters = [],
+}: {
+ websiteId: string;
+ propertyName: string;
+ propertyFilters?: PropertyFilter[];
+}) {
+ const statsQuery = useSessionDataActivityStatsQuery(websiteId, propertyName, propertyFilters);
+ const rows = statsQuery.data ?? [];
+ const { t, labels } = useMessages();
+ const { isPhone } = useMobile();
+ const activeTable = useMemo(() => rows.filter(row => row.activity > 0).slice(0, 10), [rows]);
+ const chartData = useMemo(
+ () =>
+ activeTable.map(row => ({
+ label: row.label,
+ values: {
+ sessions: row.sessions,
+ visits: row.visits,
+ views: row.views,
+ events: row.events,
+ },
+ })),
+ [activeTable],
+ );
+
+ return (
+
+
+
+ {chartData.length ? (
+
+ {t(labels.activityByProperty)}
+ row.label)}
+ datasets={[
+ {
+ label: t(labels.visitors),
+ values: chartData.map(row => row.values.sessions),
+ backgroundColor: 'rgba(59, 130, 246, 0.80)',
+ },
+ {
+ label: t(labels.visits),
+ values: chartData.map(row => row.values.visits),
+ backgroundColor: 'rgba(16, 185, 129, 0.80)',
+ },
+ {
+ label: t(labels.views),
+ values: chartData.map(row => row.values.views),
+ backgroundColor: 'rgba(245, 158, 11, 0.80)',
+ },
+ {
+ label: t(labels.events),
+ values: chartData.map(row => row.values.events),
+ backgroundColor: 'rgba(244, 114, 182, 0.80)',
+ },
+ ]}
+ stacked={true}
+ />
+
+ ) : (
+
+ )}
+
+
+
+
+ {activeTable.length === 0 ? (
+
+ ) : isPhone ? (
+
+
+
+ {row => (
+
+
+ {row.label}
+
+
+ )}
+
+
+
+ ) : (
+
+
+
+
+ {row => (
+
+
+ {row.label}
+
+
+ )}
+
+
+ {row => formatLongNumber(row.sessions)}
+
+
+ {row => formatLongNumber(row.visits)}
+
+
+ {row => formatLongNumber(row.views)}
+
+
+ {row => formatLongNumber(row.events)}
+
+
+ {row =>
+ formatShortTime(Math.abs(~~Number(row.totaltime)), ['h', 'm', 's'], ' ')
+ }
+
+
+
+
+ )}
+
+
+
+
+
+ );
+}
diff --git a/src/app/(main)/websites/[websiteId]/session-data/SessionStringPropertyView.tsx b/src/app/(main)/websites/[websiteId]/session-data/SessionStringPropertyView.tsx
deleted file mode 100644
index e8a623220..000000000
--- a/src/app/(main)/websites/[websiteId]/session-data/SessionStringPropertyView.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-'use client';
-import { LoadingPanel } from '@/components/common/LoadingPanel';
-import { useSessionDataStatsQuery } from '@/components/hooks';
-import type { PropertyFilter } from '@/lib/types';
-import { PropertyChart } from '@/components/property-data/PropertyChart';
-import { HighCardinalityPropertyChart } from './HighCardinalityPropertyChart';
-
-const HIGH_CARDINALITY_NAME_PATTERN =
- /(email|e-mail|name|(^|_)(id|uuid|token)($|_)|distinct_id|user_id|customer_id|client_id|member_id)/i;
-
-function isHighCardinalityProperty(propertyName: string, totalValues: number, uniqueValues: number) {
- if (!totalValues) return false;
-
- const uniquenessRate = uniqueValues / totalValues;
- const hasHighCardinalityName = HIGH_CARDINALITY_NAME_PATTERN.test(propertyName);
-
- return totalValues >= 20 && (hasHighCardinalityName || uniqueValues >= 20 || uniquenessRate >= 0.6);
-}
-
-export function SessionStringPropertyView({
- websiteId,
- propertyName,
- propertyFilters = [],
-}: {
- websiteId: string;
- propertyName: string;
- propertyFilters?: PropertyFilter[];
-}) {
- const statsQuery = useSessionDataStatsQuery(websiteId, propertyName, propertyFilters);
- const rows = statsQuery.data ?? [];
- const totalValues = rows.reduce((sum, row) => sum + row.sessions, 0);
- const uniqueValues = rows.length;
- const isHighCardinality = isHighCardinalityProperty(
- propertyName,
- totalValues,
- uniqueValues,
- );
-
- return (
-
- {isHighCardinality ? (
-
- ) : (
-
- )}
-
- );
-}
diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionProperties.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionProperties.tsx
index 13f7b1c60..56643d2d8 100644
--- a/src/app/(main)/websites/[websiteId]/sessions/SessionProperties.tsx
+++ b/src/app/(main)/websites/[websiteId]/sessions/SessionProperties.tsx
@@ -11,7 +11,7 @@ import { PropertyFilterButton } from '@/components/property-data/PropertyFilterB
import { PropertyNumericChart } from '@/components/property-data/PropertyNumericChart';
import { Panel } from '@/components/common/Panel';
import { SessionDataPivotTable } from '../session-data/SessionDataPivotTable';
-import { SessionStringPropertyView } from '../session-data/SessionStringPropertyView';
+import { SessionPropertyChart } from '../session-data/SessionPropertyChart';
export function SessionProperties({ websiteId }: { websiteId: string }) {
const [propertyName, setPropertyName] = useState('');
@@ -129,7 +129,7 @@ export function SessionProperties({ websiteId }: { websiteId: string }) {
/>
)}
{propertyName && selectedProperty?.dataType === DATA_TYPE.string && (
- (null);
+ const { theme } = useTheme();
+ const { colors } = useMemo(() => getThemeColors(theme), [theme]);
+
+ const chartData = useMemo(() => {
+ if (datasets?.length && labels?.length) {
+ return {
+ labels,
+ datasets: datasets.map(dataset => ({
+ label: dataset.label,
+ data: dataset.values,
+ backgroundColor: dataset.backgroundColor,
+ borderColor: dataset.borderColor || dataset.backgroundColor,
+ borderWidth: 1,
+ })),
+ };
+ }
+
+ return {
+ labels: (data || []).map(item => item.label),
+ datasets: [
+ {
+ label: '',
+ data: (data || []).map(item => item.count),
+ backgroundColor,
+ borderColor,
+ borderWidth: 1,
+ },
+ ],
+ };
+ }, [data, labels, datasets, backgroundColor, borderColor]);
+
+ const chartOptions = useMemo(
+ () => ({
+ indexAxis: horizontal ? ('y' as const) : ('x' as const),
+ scales: {
+ x: {
+ type: horizontal ? ('linear' as const) : ('category' as const),
+ min: horizontal ? 0 : undefined,
+ beginAtZero: horizontal ? true : undefined,
+ stacked,
+ grid: {
+ display: horizontal ? true : false,
+ color: colors.chart.line,
+ },
+ border: {
+ color: colors.chart.line,
+ },
+ ticks: {
+ color: colors.chart.text,
+ autoSkip: horizontal ? undefined : true,
+ maxRotation: horizontal ? undefined : 0,
+ callback: horizontal
+ ? (tickValue: string | number) => renderNumberLabels(String(tickValue))
+ : (tickValue: string | number) => chartData.labels?.[Number(tickValue)] || '',
+ },
+ },
+ y: {
+ type: horizontal ? ('category' as const) : ('linear' as const),
+ min: horizontal ? undefined : 0,
+ beginAtZero: horizontal ? undefined : true,
+ stacked,
+ grid: {
+ display: horizontal ? false : true,
+ color: colors.chart.line,
+ },
+ border: {
+ color: colors.chart.line,
+ },
+ ticks: {
+ color: colors.chart.text,
+ callback: horizontal
+ ? (tickValue: string | number) => chartData.labels?.[Number(tickValue)] || ''
+ : (tickValue: string | number) => renderNumberLabels(String(tickValue)),
+ },
+ },
+ },
+ }),
+ [chartData.labels, colors, horizontal, stacked],
+ );
+
+ const handleTooltip = useCallback(({ tooltip }: { tooltip: any }) => {
+ const { opacity, labelColors, dataPoints } = tooltip;
+ const point = dataPoints?.[0];
+ const nextTooltip = opacity
+ ? {
+ title: (point?.label ?? '').toString(),
+ color: labelColors?.[0]?.backgroundColor,
+ value: `${formatLongNumber(
+ Number(horizontal ? point?.raw?.x ?? point?.raw ?? 0 : point?.raw?.y ?? point?.raw ?? 0),
+ )}${point?.dataset?.label ? ` ${point.dataset.label}` : ''}`,
+ }
+ : null;
+
+ setTooltip(prev => {
+ if (
+ prev?.title === nextTooltip?.title &&
+ prev?.color === nextTooltip?.color &&
+ prev?.value === nextTooltip?.value
+ ) {
+ return prev;
+ }
+
+ return nextTooltip;
+ });
+ }, [horizontal]);
+
+ return (
+ <>
+
+ {tooltip && }
+ >
+ );
+}
+
+export const DistributionBarChart = memo(DistributionBarChartComponent);
+
+DistributionBarChart.displayName = 'DistributionBarChart';
diff --git a/src/components/hooks/index.ts b/src/components/hooks/index.ts
index bd508317d..a5dfd589f 100644
--- a/src/components/hooks/index.ts
+++ b/src/components/hooks/index.ts
@@ -47,7 +47,7 @@ export * from './queries/useSessionActivityQuery';
export * from './queries/useSessionDataPropertiesQuery';
export * from './queries/useSessionDataPivotQuery';
export * from './queries/useSessionDataQuery';
-export * from './queries/useSessionDataStatsQuery';
+export * from './queries/useSessionDataActivityStatsQuery';
export * from './queries/useSessionDataValuesQuery';
export * from './queries/useSessionReplaysQuery';
export * from './queries/useShareTokenQuery';
diff --git a/src/components/hooks/queries/useSessionDataStatsQuery.ts b/src/components/hooks/queries/useSessionDataActivityStatsQuery.ts
similarity index 91%
rename from src/components/hooks/queries/useSessionDataStatsQuery.ts
rename to src/components/hooks/queries/useSessionDataActivityStatsQuery.ts
index 8380fedf5..72ca11fd5 100644
--- a/src/components/hooks/queries/useSessionDataStatsQuery.ts
+++ b/src/components/hooks/queries/useSessionDataActivityStatsQuery.ts
@@ -4,7 +4,7 @@ import { useApi } from '../useApi';
import { useDateParameters } from '../useDateParameters';
import { useFilterParameters } from '../useFilterParameters';
-export function useSessionDataStatsQuery(
+export function useSessionDataActivityStatsQuery(
websiteId: string,
propertyName: string,
propertyFilters: PropertyFilter[] = [],
@@ -16,7 +16,7 @@ export function useSessionDataStatsQuery(
return useQuery({
queryKey: [
- 'websites:session-data:stats',
+ 'websites:session-data:activity-stats',
{ websiteId, propertyName, propertyFilters, startAt, endAt, unit, timezone, ...params },
],
queryFn: () =>
diff --git a/src/components/messages.ts b/src/components/messages.ts
index 79adab814..72ce903cf 100644
--- a/src/components/messages.ts
+++ b/src/components/messages.ts
@@ -191,6 +191,7 @@ export const labels: Record = {
filter: 'label.filter',
filters: 'label.filters',
propertyFilter: 'label.property-filter',
+ activityByProperty: 'label.activity-by-property',
breakdown: 'label.breakdown',
true: 'label.true',
false: 'label.false',
diff --git a/src/lib/types.ts b/src/lib/types.ts
index 587f77b96..f512c50bc 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -89,11 +89,6 @@ export interface SessionDataPivotRow {
propertyValues: string[];
}
-export interface PropertyCardinalityBucket {
- label: string;
- count: number;
-}
-
export interface PropertyLeaderboardRow {
label: string;
activity: number;
@@ -102,8 +97,6 @@ export interface PropertyLeaderboardRow {
views: number;
events: number;
totaltime: number;
- newSessions: number;
- returningSessions: number;
}
export interface QueryOptions {
diff --git a/src/queries/sql/index.ts b/src/queries/sql/index.ts
index 13800ef3e..380565471 100644
--- a/src/queries/sql/index.ts
+++ b/src/queries/sql/index.ts
@@ -48,7 +48,7 @@ export * from './sessions/getSessionDataPropertySeries';
export * from './sessions/getSessionDataNumericSeries';
export * from './sessions/getSessionDataNumericStats';
export * from './sessions/getSessionDataPivot';
-export * from './sessions/getSessionDataStats';
+export * from './sessions/getSessionDataActivityStats';
export * from './sessions/getSessionDataValues';
export * from './sessions/getSessionExpandedMetrics';
export * from './sessions/getSessionMetrics';
diff --git a/src/queries/sql/sessions/getSessionDataStats.ts b/src/queries/sql/sessions/getSessionDataActivityStats.ts
similarity index 92%
rename from src/queries/sql/sessions/getSessionDataStats.ts
rename to src/queries/sql/sessions/getSessionDataActivityStats.ts
index d0ea361cd..3da98140b 100644
--- a/src/queries/sql/sessions/getSessionDataStats.ts
+++ b/src/queries/sql/sessions/getSessionDataActivityStats.ts
@@ -4,9 +4,9 @@ import { CLICKHOUSE, PRISMA, runQuery } from '@/lib/db';
import prisma from '@/lib/prisma';
import type { PropertyFilter, PropertyLeaderboardRow, QueryFilters } from '@/lib/types';
-const FUNCTION_NAME = 'getSessionDataStats';
+const FUNCTION_NAME = 'getSessionDataActivityStats';
-export async function getSessionDataStats(
+export async function getSessionDataActivityStats(
...args: [websiteId: string, propertyName: string, filters: QueryFilters, propertyFilters?: PropertyFilter[]]
): Promise {
return runQuery({
@@ -90,9 +90,7 @@ async function relationalQuery(
coalesce(sum(session_stats.visits), 0) as visits,
coalesce(sum(session_stats.views), 0) as views,
coalesce(sum(session_stats.events), 0) as events,
- coalesce(sum(session_stats.totaltime), 0) as totaltime,
- coalesce(sum(case when session_stats.visits = 1 then 1 else 0 end), 0) as "newSessions",
- coalesce(sum(case when session_stats.visits > 1 then 1 else 0 end), 0) as "returningSessions"
+ coalesce(sum(session_stats.totaltime), 0) as totaltime
from property_values
join session_stats on session_stats.session_id = property_values.session_id
group by property_values.value
@@ -170,9 +168,7 @@ async function clickhouseQuery(
ifNull(sum(session_stats.visits), 0) as visits,
ifNull(sum(session_stats.views), 0) as views,
ifNull(sum(session_stats.events), 0) as events,
- ifNull(sum(session_stats.totaltime), 0) as totaltime,
- ifNull(sum(if(session_stats.visits = 1, 1, 0)), 0) as newSessions,
- ifNull(sum(if(session_stats.visits > 1, 1, 0)), 0) as returningSessions
+ ifNull(sum(session_stats.totaltime), 0) as totaltime
from property_values
join session_stats on session_stats.session_id = property_values.session_id
group by property_values.value
diff --git a/src/queries/sql/sessions/getSessionDataPivot.ts b/src/queries/sql/sessions/getSessionDataPivot.ts
index 5ce922008..ac4528123 100644
--- a/src/queries/sql/sessions/getSessionDataPivot.ts
+++ b/src/queries/sql/sessions/getSessionDataPivot.ts
@@ -55,16 +55,28 @@ async function relationalQuery(
${filterQuery}
${pfSQL}
),
- selected_property_sessions as (
- select distinct session_data.session_id
- from session_data
- join filtered_sessions
- on filtered_sessions.session_id = session_data.session_id
- where session_data.website_id = {{websiteId::uuid}}
- and session_data.data_key = {{propertyName}}
+ latest_session_properties as (
+ select
+ ranked.session_id,
+ ranked.data_key
+ from (
+ select
+ session_data.session_id,
+ session_data.data_key,
+ row_number() over (
+ partition by session_data.session_id, session_data.data_key
+ order by session_data.created_at desc, session_data.session_data_id desc
+ ) as row_num
+ from session_data
+ join filtered_sessions
+ on filtered_sessions.session_id = session_data.session_id
+ where session_data.website_id = {{websiteId::uuid}}
+ ) ranked
+ where ranked.row_num = 1
)
select count(*) as num
- from selected_property_sessions
+ from latest_session_properties
+ where latest_session_properties.data_key = {{propertyName}}
`,
{ ...queryParams, websiteId, propertyName, ...pfParams },
)) as { num: number }[];
@@ -83,14 +95,6 @@ async function relationalQuery(
${filterQuery}
${pfSQL}
),
- selected_property_sessions as (
- select distinct session_data.session_id
- from session_data
- join filtered_sessions
- on filtered_sessions.session_id = session_data.session_id
- where session_data.website_id = {{websiteId::uuid}}
- and session_data.data_key = {{propertyName}}
- ),
latest_session_properties as (
select
ranked.session_id,
@@ -116,17 +120,19 @@ async function relationalQuery(
order by session_data.created_at desc, session_data.session_data_id desc
) as row_num
from session_data
- join selected_property_sessions
- on selected_property_sessions.session_id = session_data.session_id
+ join filtered_sessions
+ on filtered_sessions.session_id = session_data.session_id
where session_data.website_id = {{websiteId::uuid}}
) ranked
where ranked.row_num = 1
),
paged_sessions as (
- select latest_session_properties.session_id
+ select
+ latest_session_properties.session_id,
+ latest_session_properties.created_at as sort_created_at
from latest_session_properties
- group by latest_session_properties.session_id
- order by max(latest_session_properties.created_at) desc
+ where latest_session_properties.data_key = {{propertyName}}
+ order by latest_session_properties.created_at desc
limit ${size} offset ${offset}
)
select
@@ -146,9 +152,10 @@ async function relationalQuery(
order by latest_session_properties.data_key asc
) as "propertyValues"
from latest_session_properties
- join paged_sessions on paged_sessions.session_id = latest_session_properties.session_id
- group by latest_session_properties.session_id
- order by max(latest_session_properties.created_at) desc
+ join paged_sessions
+ on paged_sessions.session_id = latest_session_properties.session_id
+ group by latest_session_properties.session_id, paged_sessions.sort_created_at
+ order by paged_sessions.sort_created_at desc
`,
{ ...queryParams, websiteId, propertyName, ...pfParams },
FUNCTION_NAME,
@@ -187,15 +194,21 @@ async function clickhouseQuery(
${filterQuery}
${pfSQL}
),
- selected_property_sessions as (
- select distinct session_data.session_id
+ latest_session_properties as (
+ select
+ session_data.session_id as session_id,
+ session_data.data_key as data_key
from session_data final
- join filtered_sessions on filtered_sessions.session_id = session_data.session_id
+ join filtered_sessions
+ on filtered_sessions.session_id = session_data.session_id
where session_data.website_id = {websiteId:UUID}
- and session_data.data_key = {propertyName:String}
+ group by
+ session_data.session_id,
+ session_data.data_key
)
select count() as num
- from selected_property_sessions
+ from latest_session_properties
+ where latest_session_properties.data_key = {propertyName:String}
`,
{ ...queryParams, websiteId, propertyName, ...pfParams },
)) as { num: number }[];
@@ -212,13 +225,6 @@ async function clickhouseQuery(
${filterQuery}
${pfSQL}
),
- selected_property_sessions as (
- select distinct session_data.session_id
- from session_data final
- join filtered_sessions on filtered_sessions.session_id = session_data.session_id
- where session_data.website_id = {websiteId:UUID}
- and session_data.data_key = {propertyName:String}
- ),
latest_session_properties as (
select
session_data.session_id as session_id,
@@ -230,8 +236,8 @@ async function clickhouseQuery(
argMax(session_data.date_value, session_data.created_at) as date_value,
max(session_data.created_at) as created_at
from session_data final
- join selected_property_sessions
- on selected_property_sessions.session_id = session_data.session_id
+ join filtered_sessions
+ on filtered_sessions.session_id = session_data.session_id
where session_data.website_id = {websiteId:UUID}
group by
session_data.session_id,
@@ -239,10 +245,11 @@ async function clickhouseQuery(
),
paged_sessions as (
select
- latest_session_properties.session_id
+ latest_session_properties.session_id,
+ latest_session_properties.created_at as sort_created_at
from latest_session_properties
- group by latest_session_properties.session_id
- order by max(latest_session_properties.created_at) desc
+ where latest_session_properties.data_key = {propertyName:String}
+ order by latest_session_properties.created_at desc
limit ${size} offset ${offset}
)
select
@@ -262,8 +269,9 @@ async function clickhouseQuery(
join paged_sessions
on paged_sessions.session_id = latest_session_properties.session_id
group by
- latest_session_properties.session_id
- order by createdAt desc
+ latest_session_properties.session_id,
+ paged_sessions.sort_created_at
+ order by paged_sessions.sort_created_at desc
`,
{ ...queryParams, websiteId, propertyName, ...pfParams },
FUNCTION_NAME,
diff --git a/src/queries/sql/sessions/getSessionDataValues.ts b/src/queries/sql/sessions/getSessionDataValues.ts
index e015e30ef..1c7434768 100644
--- a/src/queries/sql/sessions/getSessionDataValues.ts
+++ b/src/queries/sql/sessions/getSessionDataValues.ts
@@ -31,7 +31,7 @@ async function relationalQuery(
`
select
array_item.value as "value",
- count(distinct session_data.session_id) as "total"
+ count(*) as "total"
from website_event
${cohortQuery}
${joinSessionQuery}
@@ -46,7 +46,7 @@ async function relationalQuery(
${filterQuery}
group by array_item.value
order by 2 desc
- limit 100
+ limit 500
`,
queryParams,
FUNCTION_NAME,
@@ -61,7 +61,7 @@ async function relationalQuery(
when data_type = 4 then ${getDateSQL('date_value', 'hour')}
else string_value
end as "value",
- count(distinct session_data.session_id) as "total"
+ count(*) as "total"
from website_event
${cohortQuery}
${joinSessionQuery}
@@ -75,7 +75,7 @@ async function relationalQuery(
${filterQuery}
group by value
order by 2 desc
- limit 100
+ limit 500
`,
queryParams,
FUNCTION_NAME,
@@ -95,7 +95,7 @@ async function clickhouseQuery(
`
select
arrayJoin(JSONExtract(ifNull(session_data.string_value, '[]'), 'Array(String)')) as "value",
- uniq(session_data.session_id) as "total"
+ count() as "total"
from website_event
${cohortQuery}
join session_data final
@@ -108,7 +108,7 @@ async function clickhouseQuery(
${filterQuery}
group by value
order by 2 desc
- limit 100
+ limit 500
`,
queryParams,
FUNCTION_NAME,
@@ -121,7 +121,7 @@ async function clickhouseQuery(
multiIf(data_type = 2, replaceAll(string_value, '.0000', ''),
data_type = 4, toString(date_trunc('hour', date_value)),
string_value) as "value",
- uniq(session_data.session_id) as "total"
+ count() as "total"
from website_event
${cohortQuery}
join session_data final
@@ -134,7 +134,7 @@ async function clickhouseQuery(
${filterQuery}
group by value
order by 2 desc
- limit 100
+ limit 500
`,
queryParams,
FUNCTION_NAME,