【发布时间】:2016-10-03 04:55:23
【问题描述】:
我必须构建一个 WHERE 子句,通过格式化包含员工详细信息的 xml 来搜索员工。
我已将 xml 数据移至临时表并使用 CTE 查询来获取每个节点的描述。我面临将子元素分组到必须为多个级别完成的父元素的问题。
最终条件为 Null 的父元素必须填充子元素的最终条件,直到顶层,如下面的屏幕截图所示。
请在下面找到 sql 查询和所需的输出:
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
样本数据
期望的输出
(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'))
【问题讨论】:
-
请提供一个视觉示例,说明您希望如何正确格式化数据。我很难理解您发布的带注释的屏幕截图。
-
请看这里如何提问:spaghettidba.com/2015/04/24/…
-
我已经编辑了问题并添加了 sql 查询和所需的输出。抱歉之前的格式不好。感谢您的帮助。
标签: sql-server