diff --git a/src/components/Search/FilterDropdowns/GroupByPopup.tsx b/src/components/Search/FilterDropdowns/GroupByPopup.tsx
new file mode 100644
index 000000000000..949152ff8dae
--- /dev/null
+++ b/src/components/Search/FilterDropdowns/GroupByPopup.tsx
@@ -0,0 +1,119 @@
+import React, {useCallback, useMemo, useState} from 'react';
+import {View} from 'react-native';
+import Button from '@components/Button';
+import type {SearchGroupBy} from '@components/Search/types';
+import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
+import type {ListItem} from '@components/SelectionList/types';
+import Text from '@components/Text';
+import useLocalize from '@hooks/useLocalize';
+import useResponsiveLayout from '@hooks/useResponsiveLayout';
+import useThemeStyles from '@hooks/useThemeStyles';
+import useWindowDimensions from '@hooks/useWindowDimensions';
+import type {GroupBySection} from '@libs/SearchUIUtils';
+import CONST from '@src/CONST';
+
+type GroupByPopupItem = {
+    text: string;
+    value: SearchGroupBy;
+};
+
+type GroupByPopupProps = {
+    /** The label to show when in an overlay on mobile */
+    label?: string;
+
+    /** The grouped options to show in the list */
+    sections: GroupBySection[];
+
+    /** The currently selected item */
+    value: GroupByPopupItem | null;
+
+    /** Function to call to close the overlay when changes are applied */
+    closeOverlay: () => void;
+
+    /** Function to call when changes are applied */
+    onChange: (item: GroupByPopupItem | null) => void;
+};
+
+function GroupByPopup({label, value, sections, closeOverlay, onChange}: GroupByPopupProps) {
+    const {translate} = useLocalize();
+    const styles = useThemeStyles();
+    // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
+    const {isSmallScreenWidth} = useResponsiveLayout();
+    const {windowHeight} = useWindowDimensions();
+    const [selectedItem, setSelectedItem] = useState(value);
+
+    const allSelectableItems = useMemo(() => sections.flatMap((section) => section.options), [sections]);
+
+    const listSections = useMemo(
+        () =>
+            sections.map((section) => ({
+                sectionIndex: section.sectionIndex,
+                ...(section.sectionIndex > 0 ? {customHeader: <View style={styles.dividerLine} />} : {}),
+                data: section.options.map<ListItem<SearchGroupBy>>((item) => ({
+                    text: item.text,
+                    keyForList: item.value,
+                    isSelected: item.value === selectedItem?.value,
+                })),
+            })),
+        [sections, selectedItem?.value, styles.dividerLine],
+    );
+
+    const optionsCount = Math.max(
+        1,
+        listSections.reduce((count, section) => count + section.data.length + (section.data.length > 0 && !!section.customHeader ? 1 : 0), 0),
+    );
+
+    const updateSelectedItem = useCallback(
+        (item: ListItem) => {
+            const newItem = allSelectableItems.find((option) => option.value === item.keyForList) ?? null;
+            setSelectedItem(newItem);
+        },
+        [allSelectableItems],
+    );
+
+    const applyChanges = useCallback(() => {
+        onChange(selectedItem);
+        closeOverlay();
+    }, [closeOverlay, onChange, selectedItem]);
+
+    const resetChanges = useCallback(() => {
+        onChange(null);
+        closeOverlay();
+    }, [closeOverlay, onChange]);
+
+    return (
+        <View style={[!isSmallScreenWidth && styles.pv4, styles.gap2]}>
+            {isSmallScreenWidth && !!label && <Text style={[styles.textLabel, styles.textSupporting, styles.ph5, styles.pv1]}>{label}</Text>}
+
+            <View style={[styles.getSelectionListPopoverHeight(optionsCount, windowHeight, false)]}>
+                <SelectionListWithSections
+                    sections={listSections}
+                    shouldSingleExecuteRowSelect
+                    ListItem={SingleSelectListItem}
+                    onSelectRow={updateSelectedItem}
+                />
+            </View>
+
+            <View style={[styles.flexRow, styles.gap2, styles.ph5]}>
+                <Button
+                    medium
+                    style={[styles.flex1]}
+                    text={translate('common.reset')}
+                    onPress={resetChanges}
+                    sentryLabel={CONST.SENTRY_LABEL.SEARCH.FILTER_POPUP_RESET_SINGLE_SELECT}
+                />
+                <Button
+                    success
+                    medium
+                    style={[styles.flex1]}
+                    text={translate('common.apply')}
+                    onPress={applyChanges}
+                    sentryLabel={CONST.SENTRY_LABEL.SEARCH.FILTER_POPUP_APPLY_SINGLE_SELECT}
+                />
+            </View>
+        </View>
+    );
+}
+
+export default GroupByPopup;
diff --git a/src/components/Search/SearchPageHeader/useSearchFiltersBar.tsx b/src/components/Search/SearchPageHeader/useSearchFiltersBar.tsx
index 73756b66bcad..8102aa915909 100644
--- a/src/components/Search/SearchPageHeader/useSearchFiltersBar.tsx
+++ b/src/components/Search/SearchPageHeader/useSearchFiltersBar.tsx
@@ -5,6 +5,7 @@ import type {OnyxCollection} from 'react-native-onyx';
 import {usePersonalDetails} from '@components/OnyxListItemProvider';
 import type {SearchDateValues} from '@components/Search/FilterComponents/DatePresetFilterBase';
 import type {PopoverComponentProps} from '@components/Search/FilterDropdowns/DropdownButton';
+import GroupByPopup from '@components/Search/FilterDropdowns/GroupByPopup';
 import type {MultiSelectItem} from '@components/Search/FilterDropdowns/MultiSelectPopup';
 import MultiSelectPopup from '@components/Search/FilterDropdowns/MultiSelectPopup';
 import SingleSelectPopup from '@components/Search/FilterDropdowns/SingleSelectPopup';
@@ -33,6 +34,7 @@ import {
     filterValidHasValues,
     getFeedOptions,
     getGroupByOptions,
+    getGroupBySections,
     getGroupCurrencyOptions,
     getHasOptions,
     getStatusOptions,
@@ -165,6 +167,7 @@ function useSearchFiltersBar(queryJSON: SearchQueryJSON, isMobileSelectionModeEn
     const type = typeOptions.find((option) => option.value === unsafeType) ?? null;
 
     const groupByOptions = getGroupByOptions(translate);
+    const groupBySections = getGroupBySections(translate);
     const groupBy = groupByOptions.find((option) => option.value === unsafeGroupBy) ?? null;
 
     const viewOptions = getViewOptions(translate);
@@ -283,9 +286,9 @@ function useSearchFiltersBar(queryJSON: SearchQueryJSON, isMobileSelectionModeEn
     );
 
     const groupByComponent = ({closeOverlay}: PopoverComponentProps) => (
-        <SingleSelectPopup
+        <GroupByPopup
             label={translate('search.groupBy')}
-            items={groupByOptions}
+            sections={groupBySections}
             value={groupBy}
             closeOverlay={closeOverlay}
             onChange={(item) => {
diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts
index 31907d214b8e..40584fc5538b 100644
--- a/src/libs/SearchUIUtils.ts
+++ b/src/libs/SearchUIUtils.ts
@@ -163,6 +163,10 @@ import ViolationsUtils from './Violations/ViolationsUtils';
 
 type ColumnSortMapping<T> = Partial<Record<SearchColumnType, keyof T | null>>;
 type ColumnVisibility = Partial<Record<SearchColumnType, boolean>>;
+type GroupBySection = {
+    sectionIndex: number;
+    options: Array<SingleSelectItem<SearchGroupBy>>;
+};
 
 // List Item sorting
 type TransactionSorting = ColumnSortMapping<TransactionListItemType>;
@@ -3989,6 +3993,30 @@ function getGroupByOptions(translate: LocalizedTranslate) {
     return Object.values(CONST.SEARCH.GROUP_BY).map<SingleSelectItem<SearchGroupBy>>((value) => ({text: translate(`search.filters.groupBy.${value}`), value}));
 }
 
+function getGroupBySections(translate: LocalizedTranslate): GroupBySection[] {
+    const getOption = (groupBy: SearchGroupBy): SingleSelectItem<SearchGroupBy> => ({
+        text: translate(`search.filters.groupBy.${groupBy}`),
+        value: groupBy,
+    });
+    return [
+        {
+            options: [getOption(CONST.SEARCH.GROUP_BY.FROM), getOption(CONST.SEARCH.GROUP_BY.CARD)],
+        },
+        {
+            options: [getOption(CONST.SEARCH.GROUP_BY.CATEGORY), getOption(CONST.SEARCH.GROUP_BY.MERCHANT), getOption(CONST.SEARCH.GROUP_BY.TAG)],
+        },
+        {
+            options: [getOption(CONST.SEARCH.GROUP_BY.MONTH), getOption(CONST.SEARCH.GROUP_BY.WEEK), getOption(CONST.SEARCH.GROUP_BY.YEAR), getOption(CONST.SEARCH.GROUP_BY.QUARTER)],
+        },
+        {
+            options: [getOption(CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID)],
+        },
+    ].map((section, sectionIndex) => ({
+        ...section,
+        sectionIndex,
+    }));
+}
+
 function getViewOptions(translate: LocalizedTranslate) {
     return Object.values(CONST.SEARCH.VIEW).map<SingleSelectItem<SearchView>>((value) => ({text: translate(`search.view.${value}`), value}));
 }
@@ -4754,6 +4782,7 @@ export {
     getStatusOptions,
     getTypeOptions,
     getGroupByOptions,
+    getGroupBySections,
     getViewOptions,
     getGroupCurrencyOptions,
     getFeedOptions,
@@ -4784,4 +4813,4 @@ export {
     isEligibleForApproveSuggestion,
     applySelectionToItem,
 };
-export type {SavedSearchMenuItem, SearchTypeMenuSection, SearchTypeMenuItem, SearchDateModifier, SearchDateModifierLower, SearchKey, ArchivedReportsIDSet};
+export type {SavedSearchMenuItem, SearchTypeMenuSection, SearchTypeMenuItem, SearchDateModifier, SearchDateModifierLower, SearchKey, ArchivedReportsIDSet, GroupBySection};
diff --git a/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersGroupByPage.tsx b/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersGroupByPage.tsx
index 041db1c1441f..e94425fdbf7c 100644
--- a/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersGroupByPage.tsx
+++ b/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersGroupByPage.tsx
@@ -5,15 +5,15 @@ import FixedFooter from '@components/FixedFooter';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import ScreenWrapper from '@components/ScreenWrapper';
 import type {SearchGroupBy} from '@components/Search/types';
-import SelectionList from '@components/SelectionList';
 import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
 import type {ListItem} from '@components/SelectionList/types';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {updateAdvancedFilters} from '@libs/actions/Search';
 import Navigation from '@libs/Navigation/Navigation';
-import {getGroupByOptions} from '@libs/SearchUIUtils';
+import {getGroupBySections} from '@libs/SearchUIUtils';
 import ONYXKEYS from '@src/ONYXKEYS';
 import ROUTES from '@src/ROUTES';
 
@@ -23,14 +23,17 @@ function SearchFiltersGroupByPage() {
     const [searchAdvancedFiltersForm] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM);
     const [selectedItem, setSelectedItem] = useState(searchAdvancedFiltersForm?.groupBy);
 
-    const listData: Array<ListItem<SearchGroupBy>> = useMemo(() => {
-        return getGroupByOptions(translate).map((groupOption) => ({
-            text: groupOption.text,
-            keyForList: groupOption.value,
-            isSelected: selectedItem === groupOption.value,
+    const sections = useMemo(() => {
+        return getGroupBySections(translate).map((section) => ({
+            sectionIndex: section.sectionIndex,
+            ...(section.sectionIndex > 0 ? {customHeader: <View style={styles.dividerLine} />} : {}),
+            data: section.options.map<ListItem<SearchGroupBy>>((groupOption) => ({
+                text: groupOption.text,
+                keyForList: groupOption.value,
+                isSelected: selectedItem === groupOption.value,
+            })),
         }));
-    }, [translate, selectedItem]);
-
+    }, [selectedItem, styles.dividerLine, translate]);
     const updateSelectedItem = useCallback((type: ListItem<SearchGroupBy>) => {
         setSelectedItem(type?.keyForList ?? undefined);
     }, []);
@@ -60,9 +63,9 @@ function SearchFiltersGroupByPage() {
                 }}
             />
             <View style={[styles.flex1]}>
-                <SelectionList
+                <SelectionListWithSections
                     shouldSingleExecuteRowSelect
-                    data={listData}
+                    sections={sections}
                     ListItem={SingleSelectListItem}
                     onSelectRow={updateSelectedItem}
                 />
