I have to build a WHERE
clause for searching employees by formatting a xml which consist of employee details.
I have moved the xml data to a temp table and used CTE
query to get each node description. I'm facing problem to group the child elements to a parent which has to be done for multiple levels.
The parent element which has the Final Condition as Null has to be filled with the final condition of the children until the top level as shown in the below screen shot.
Please find the sql query and desired output below:
DECLARE @SearchCriteriaXML XML
DECLARE @TempTable TABLE
(
ParentName NVARCHAR(250)
,LocalName NVARCHAR(250)
,FilterType NVARCHAR(MAX)
,Property NVARCHAR(250)
,Comparator NVARCHAR(250)
,ComparatorCondition NVARCHAR(250)
,ComparatorSign NVARCHAR(250)
,value NVARCHAR(MAX)
,InternalType NVARCHAR(MAX)
,FinalCondition NVARCHAR(MAX)
,Id int
,Parentid int
);
SET @SearchCriteriaXML =
N'<searchcriteria>
<filter type=''and''>
<filter type=''or''>
<filter type=''and''>
<condition property =''group'' comparator =''equals'' value=''Regional West Sales Team'' />
<condition property =''group'' comparator =''equals'' value=''Everyone Christmas 2016'' not=''true'' />
<filter type=''or''>
<condition property =''lastname'' comparator =''equals'' value=''John'' />
<condition property =''lastname'' comparator =''equals'' value=''Miller'' />
</filter>
<condition property =''State'' comparator =''equals'' value=''California'' />
</filter>
<filter type=''and''>
<condition property =''group'' comparator =''equals'' value=''Metro West Sales Team'' />
<condition property =''group'' comparator =''equals'' value=''Everyone Christmas 2016 1'' not=''true'' />
<filter type=''or''>
<condition property =''lastname'' comparator =''equals'' value=''John 1'' />
<condition property =''lastname'' comparator =''equals'' value=''Miller 1'' />
</filter>
<condition property =''State'' comparator =''equals'' value=''Virginia'' />
</filter>
</filter>
<condition property =''company'' comparator =''equals'' value=''Test Company'' />
</filter>
</searchcriteria>'
DECLARE @idoc int, @doc varchar(1000);
EXEC sp_xml_preparedocument @idoc OUTPUT, @SearchCriteriaXML;
--SELECT * into #temp
--FROM OPENXML (@idoc, 'searchcriteria//*')
;WITH CTE
AS(
-- SELECT stmt using OPENXML rowset provider
SELECT *
FROM OPENXML (@idoc, '/searchcriteria//*')
WITH
(
ParentName NVARCHAR(400) '@mp:parentlocalname'
,LocalName NVARCHAR(400) '@mp:localname'
,Prefix NVARCHAR(200) '@mp:prev'
,[type] NVARCHAR(100) '@type'
,[Internaltype] NVARCHAR(100) '../@type'
,[property] NVARCHAR(100) '@property'
,[comparator] NVARCHAR(250) '@comparator'
,[comparatorCondition] NVARCHAR(250) '@not'
,[value] NVARCHAR(250) '@value',
[id] int '@mp:id',
[parentid] int '@mp:parentid'
))
INSERT INTO @TempTable
SELECT ParentName,LocalName,[type] AS FilterType,property,comparator,[comparatorCondition],
CASE
WHEN comparator = 'equals' AND [comparatorCondition] = 'true' THEN '<>'
WHEN comparator = 'equals' THEN '='
WHEN comparator = 'greaterthan' THEN '>'
WHEN comparator = 'lessthan' THEN '<'
WHEN comparator = 'greaterthanorequal' THEN '>='
WHEN comparator = 'lessthanorequal' THEN '<='
END AS ComparatorSign
,value
,[Internaltype]
, NULL AS FinalCondition,
[id],
[parentid]
FROM CTE ORDER BY [parentid] DESC
UPDATE @TempTable SET
FinalCondition =
CASE WHEN LocalName = 'condition' THEN ISNULL(property,'') + ' ' + ISNULL(ComparatorSign,'') + ' '+ ''''+ISNULL(value,'')+'''' END
select * from @TempTable
;With EmployeeDetails (Id, ParentId, FilterType, FinalCondition, Level)
AS
(
SELECT Id, Parentid, FilterType, FinalCondition, Plevel = 1 FROM @TempTable WHERE Parentid = 0
UNION ALL
SELECT t.Id, t.Parentid, t.FilterType, t.FinalCondition,
Plevel = e.Level + 1 FROM @TempTable t INNER JOIN EmployeeDetails e on e.Id = t.ParentId
)
select * from EmployeeDetails
Sample data
Desired output
(company = 'Test Company') and
((group = 'Metro West Sales Team' and group <> 'Everyone Christmas 2016 1' and (lastname = 'John 1' or lastname = 'Miller 1') and State = 'Virginia') or
(group = 'Regional West Sales Team' and group <> 'Everyone Christmas 2016' and (lastname = 'John1' or lastname = 'Miller1') and State = 'California'))