0

源数据看起来来自以下描述美国职业棒球大联盟比赛的免费 XML 文件。

http://gd2.mlb.com/components/game/mlb/year_2013/month_04/day_09/gid_2013_04_09_atlmlb_miamlb_1/inning/

我创建了一个 SQL Server 表,其中包含每个 GamePK/局的一行,以及一个名为 PBP 的 XML 列。上面文件夹中的每个文件都成为此表中的一行。下面的查询是我尝试将 XML 解析为记录集。它可以工作,但对于大量行来说非常慢,而且非常重复 - 似乎应该有更好的方法来做到这一点而没有 UNION 子句。感谢您对改进/优化的任何帮助

select 
 i.GamePK
 ,inn.value('@num', 'int') as inning
 ,itop.value('1', 'int') as IsTop
 ,itop.value('@num', 'int') as abNum
 ,itop.value('@batter', 'int') as batter
--  clip

 ,itoppit.value('@des', 'varchar(32)') as pitdesc
 ,itoppit.value('@id', 'int') as seq
 ,itoppit.value('@type', 'varchar(8)') as pittype
-- clip 

 from tblInnings i
       cross apply PBP.nodes('/inning') as inn(inn)
       cross apply inn.nodes('top/atbat') as itop(itop)
       cross apply itop.nodes('pitch') as itoppit(itoppit)
union 
select 
 i.GamePK
 ,inn.value('@num', 'int') as inning
 ,ibot.value('0', 'int') as IsTop
 ,ibot.value('@num', 'int') as abNum
 ,ibot.value('@batter', 'int') as batter
-- clip 

 ,ibotpit.value('@des', 'varchar(32)') as pitdesc
 ,ibotpit.value('@id', 'int') as seq
 ,ibotpit.value('@type', 'varchar(8)') as pittype
--clip

 from tblInnings i
       cross apply PBP.nodes('/inning') as inn(inn)
       cross apply inn.nodes('bottom/atbat') as ibot(ibot)
       cross apply ibot.nodes('pitch') as ibotpit(ibotpit)
4

1 回答 1

0

如果您使用的是最新版本的 SQL Server,则有一种新的列数据类型 (XML)。

您可以对其应用 xpath,从而更轻松地查询该列。

我建议您将其实际存储为 XML,并将其视为 XML,而不是尝试将 XML 作为字符串存储在您的数据库中。

有一个学习曲线。您需要熟悉 XPATH,但这不是火箭科学。

一个例子:

SELECT Id, PartitionMonth, EmailAddress, AcquisitionCodeId, FieldValues.value('
declare namespace s="http://domain.com/FieldValues.xsd";
data(/s:FieldValues/s:item/@value)[1]', 'varchar(200)')
FROM Leads.Leads WITH (NOLOCK)
 WHERE Id = 190708

另一个按键检索值的示例:

SELECT r.EmailAddress, ar.Ip, ar.DateLog, 
  ar.FieldValues.value('
  declare namespace s="http://domain.com/FieldValues.xsd";
  data(/s:FieldValues/s:item[@key="First Name"]/@value)[1]', 'varchar(20)') FirstName,
  ar.FieldValues.value('
  declare namespace s="http://domain.com/FieldValues.xsd";
  data(/s:FieldValues/s:item[@key="Last Name"]/@value)[1]', 'varchar(20)') LastName
FROM Records.Records r WITH (NOLOCK)
JOIN Records.AcquisitionRecords ar WITH (NOLOCK) ON r.Id = ar.Id
WHERE ar.AcquisitionCodeId IN (19, 21, 30, 34, 36)
AND ar.DateLog BETWEEN '1-mar-09' AND '31-mar-09'

在 SQL Server 中开始使用 XML 的好地方 http://msdn.microsoft.com/en-US/library/ms189887(v=sql.90).aspx

于 2013-04-10T23:37:25.117 回答