3

次のようなテーブルがあります。

CREATE TABLE CustomerXmlData
(CustomerId int,
CustomerData xml)

CustomerId はメインの顧客テーブルにリンクし、CustomerData は次のような xml ドキュメントです。

<Person>
  <Product>
    <Name>ABC</Name>
    <Value>500</Value>
  </Product>
  <Product>
    <Name>XYZ</Name>
    <Value>600</Value>
  </Product>
</Person>

そのような行は数十万あります。擬似コードでやりたいことは、「where = 'XYZ' の平均Valueを求める」です。ProductName

要素の属性に基づいて、またはドキュメント内で一意の親を持つことに基づいて値を取得する方法は知っていますが、この状況ではどちらも役に立ちません。Name必要なものを見つけて、次の兄弟の値を取得できるものは何も見つかりません。

エッジ テーブルを使用FOR XMLして作成することはできますが、カーソルを使用してそれをループする必要がありますか? より効率的な解決策を期待しています。

4

2 に答える 2

6

必要な名前を見つけて、次の兄弟の値を取得できるものが見つかりません。

declare @Name varchar(10)
set @Name = 'XYZ'

select N.value('.', 'int') as Value    
from CustomerXmlData
  cross apply CustomerData.nodes
    ('/Person/Product[Name = sql:variable("@Name")]/Value') as T(N)
于 2012-05-04T11:44:49.057 に答える
2

これを試してください(名前でフィルタリングするように編集):

DECLARE @Name VARCHAR(50)
SET @Name = 'XYZ'

SELECT Name, AVG(Value) 
FROM (
SELECT 
    c.value('Name[1]', 'VARCHAR(50)') AS Name
    , c.value('Value[1]', 'DECIMAL') AS Value
FROM CustomerXmlData
CROSS APPLY CustomerData.nodes('//Product[Name = sql:variable("@Name")]') AS t(c)
) T
GROUP BY Name
于 2012-05-04T11:11:09.123 に答える