在SQL Server中我试图查询具有XML列的表,该列中的XML类似于下面的
DECLARE @XML AS XML
SET @XML =
'<Root>
<Stuff>
<InsideStuff>1</InsideStuff>
<InsideStuff>2</InsideStuff>
<StuffIDontWant>9</StuffIDontWant>
</Stuff>
<Stuff>
<InsideStuff>3</InsideStuff>
<InsideStuff>4</InsideStuff>
<StuffIDontWant>6</StuffIDontWant>
<StuffIDontWant>7</StuffIDontWant>
</Stuff>
</Root>'
SELECT TableAlias.ColumnAlias.value('(.)','nvarchar(max)')
FROM @XML.nodes('/Root/Stuff/InsideStuff') AS TableAlias(ColumnAlias)
上面的代码会给我1,2,3,4这就是我想要的,但是我似乎无法弄清楚如何将其作为一种连接格式,我想做的事情就像
SELECT T1.Name
FROM TableOne T1
INNER JOIN TableWithXml.ColumnWithXml.nodes('/Root/Stuff/InsideStuff') AS TableAlias(ColumnAlias) ON T1.ID = TableAlias(ColumnAlias)
在这种情况下如何格式化我的T-SQL?
答案 0 :(得分:1)
主要目标是将XML展平到所需级别,并将其展平到可在查询中使用的表格中。
假设的表格结构:
DECLARE @TableWithXml TABLE (
ID int IDENTITY(1,1),
XmlCol XML
);
DECLARE @TableOne TABLE (
ID int IDENTITY(1,1),
StuffId int
);
解决方案1 :如果您不关心除xml是否包含给定值之外的任何其他数据,只需将其展平一级并检查值:(sqlfiddle ):
SELECT t1.ID as T1ID, t2.ID as TXID, t2.XmlCol
FROM @TableOne t1
CROSS JOIN @TableWithXml t2
WHERE t1.StuffId IN (
SELECT XmlData.InsideStuff.value('(.)','int') as InsideStuff
FROM @TableWithXml tX
CROSS APPLY tX.XmlCol.nodes('/Root/Stuff/InsideStuff') as XmlData(InsideStuff)
WHERE tX.ID = t2.ID
);
-- // Or alternatively...
SELECT t1.ID as T1ID, FlattenedTable.TXID, FlattenedTable.InsideStuff, FlattenedTable.XmlCol
FROM @TableOne t1
INNER JOIN (
SELECT tx.ID as TXID, tx.XmlCol, XmlData.InsideStuff.value('(.)','int') as InsideStuff
FROM @TableWithXml tX
CROSS APPLY tX.XmlCol.nodes('/Root/Stuff/InsideStuff') as XmlData(InsideStuff)
) as FlattenedTable ON t1.StuffId = FlattenedTable.InsideStuff
解决方案2 :如果您想使用XML数据,请将其展平(sqlfiddle):
SELECT t1.ID as T1ID,
tx.ID as TXID,
Stuffs_InsideStuff.val.value('(.)', 'int') as InsideStuffId,
Stuffs_StuffIDontWant.val.value('(.)', 'nvarchar(max)') as StuffIDontWant
FROM @TableOne t1
INNER JOIN (
@TableWithXml tX
CROSS APPLY tX.xmlCol.nodes('/Root/Stuff') as XmlData(Stuffs)
CROSS APPLY XmlData.Stuffs.nodes('InsideStuff') as Stuffs_InsideStuff(val)
CROSS APPLY XmlData.Stuffs.nodes('StuffIDontWant') as Stuffs_StuffIDontWant(val)
) on t1.stuffId = Stuffs_InsideStuff.val.value('(.)', 'int');