Ниже приведен пример задачи, над которой я работаю, и я хотел бы знать, есть ли способ выполнить указанные ниже операции за один проход вместо трех. Я извлекаю данные дочернего узла из 3 узлов документа, а затем объединяю их в одну запись на основе «имени поля». Запрос ниже является эффективным, однако мне было бы любопытно, есть ли способ выполнить обработку данных за один проход вместо 3?
DECLARE @T TABLE(MenuID INT, DefaultListView NVARCHAR(MAX)) -- <-- This is this way in the DB
INSERT @T VALUES
(1,
'<ListPageUserPreference xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SelectFields>
<ListPageUPSelectField>
<FieldName>AbstractPreparedBy</FieldName>
<DisplayIndex>14</DisplayIndex>
<FieldWidth>112</FieldWidth>
</ListPageUPSelectField>
<ListPageUPSelectField>
<FieldName>AccountingType</FieldName>
<DisplayIndex>3</DisplayIndex>
<FieldWidth>112</FieldWidth>
</ListPageUPSelectField>
<ListPageUPSelectField>
<FieldName>BuildingAddress_1</FieldName>
<DisplayIndex>4</DisplayIndex>
<FieldWidth>112</FieldWidth>
</ListPageUPSelectField>
<ListPageUPSelectField>
<FieldName>BuildingName</FieldName>
<DisplayIndex>0</DisplayIndex>
<FieldWidth>112</FieldWidth>
</ListPageUPSelectField>
<ListPageUPSelectField>
<FieldName>BuildingCity</FieldName>
<DisplayIndex>5</DisplayIndex>
<FieldWidth>112</FieldWidth>
</ListPageUPSelectField>
<ListPageUPSelectField>
<FieldName>BuildingCountry</FieldName>
<DisplayIndex>2</DisplayIndex>
<FieldWidth>112</FieldWidth>
</ListPageUPSelectField>
<ListPageUPSelectField>
<FieldName>EndDate</FieldName>
<DisplayIndex>8</DisplayIndex>
<FieldWidth>112</FieldWidth>
</ListPageUPSelectField>
</SelectFields>
<GroupByFields>
<ListPageUPGroupByColumn>
<GroupByIndex>0</GroupByIndex>
<GroupByField>BuildingCountry</GroupByField>
</ListPageUPGroupByColumn>
</GroupByFields>
<SortByFields>
<ListPageUPSortByColumn>
<SortByIndex>0</SortByIndex>
<SortByField>BuildingCountry</SortByField>
<SortDirection>Descending</SortDirection>
</ListPageUPSortByColumn>
</SortByFields>
<PageSize>50</PageSize>
<FilterOption>0</FilterOption>
<Filter>[LeaseActive] = True</Filter>
<distinct/>
<ArchiveActive>1</ArchiveActive>
<ExpandAll>false</ExpandAll>
</ListPageUserPreference>')
;WITH XmlData AS
(
SELECT
MenuID,
XmlNodes = CAST(DefaultListView AS XML)
FROM
@T
)
,GridLevelData AS
(
SELECT
MenuID,
PageSize = ISNULL(XmlNodes.value('(/ListPageUserPreference/PageSize)[1]', 'INT'), 25),
FilterOption = ISNULL(XmlNodes.value('(/ListPageUserPreference/FilterOption)[1]', 'INT'),0),
Filter = XmlNodes.value('(/ListPageUserPreference/Filter)[1]', 'NVARCHAR(MAX)'),
ArchiveActive = ISNULL(XmlNodes.value('(/ListPageUserPreference/ArchiveActive)[1]', 'INT'),0),--!!!
ExpandAll = ISNULL(XmlNodes.value('(/ListPageUserPreference/ExpandAll)[1]', 'BIT'),0),---!!!
IsDistinct = ISNULL(XmlNodes.exist('(/ListPageUserPreference/distinct)[1]'),0)---!!!
FROM
XmlData
)
,SelectedFields AS
(
SELECT
MenuID,
FieldName = Fields.Field.value('(FieldName)[1]', 'VARCHAR(150)'),
DisplayIndex = Fields.Field.value('(DisplayIndex)[1]', 'INT'),
FieldWidth = Fields.Field.value('(FieldWidth)[1]', 'INT')
FROM
XmlData
CROSS APPLY XmlNodes.nodes('/ListPageUserPreference/SelectFields/ListPageUPSelectField') AS Fields(Field)
)
,GroupingFields AS
(
SELECT
MenuID,
FieldName = Fields.Field.value('(GroupByField)[1]', 'VARCHAR(150)'),
GroupByIndex = Fields.Field.value('(GroupByIndex)[1]', 'INT')
FROM
XmlData
CROSS APPLY XmlNodes.nodes('/ListPageUserPreference/GroupByFields/ListPageUPGroupByColumn') AS Fields(Field)
)
,SortingFields AS
(
SELECT
MenuID,
FieldName = Fields.Field.value('(SortByField)[1]', 'NVARCHAR(50)'),
SortByIndex = Fields.Field.value('(SortByIndex)[1]', 'INT'),
SortDirection = Fields.Field.value('(SortDirection)[1]', 'NVARCHAR(50)')
FROM
XmlData
CROSS APPLY XmlNodes.nodes('/ListPageUserPreference/SortByFields/ListPageUPSortByColumn') AS Fields(Field)
)
,FieldsCombinedAndNormalized AS
(
SELECT
SF.MenuID,
SF.FieldName,
visibleIndex = SF.DisplayIndex,
FieldWidth = CASE WHEN ISNULL(SF.FieldWidth,0) = 0 THEN 100 ELSE SF.FieldWidth END, --!!!
IsGrouped = CASE WHEN GF.MenuID IS NULL THEN 0 ELSE 1 END,
GroupByIndex = ISNULL(GF.GroupByIndex,0),
IsSorted = CASE WHEN SR.MenuID IS NULL THEN 0 ELSE 1 END,
SortByIndex = ISNULL(SR.SortByIndex,0),
SortDirection = SR.SortDirection,
DisplayIndex
FROM
SelectedFields SF
LEFT OUTER JOIN GroupingFields GF ON GF.MenuID = SF.MenuID AND GF.FieldName = SF.FieldName
LEFT OUTER JOIN SortingFields SR ON SR.MenuID = SF.MenuID AND SR.FieldName = SF.FieldName
)
SELECT * FROM FieldsCombinedAndNormalized