从父xml中获取数据,该数据在SQL Server

时间:2017-04-11 11:54:46

标签: sql-server xquery xquery-sql

我有一个xml,其父标记基于它的modelType具有不同的子标记。 我想要的只是在一个Select查询中获取这些不同的子标签数据。

这是我的xml

<rateModelList>
        <rateModel>
            <intRateModelID>1</intRateModelID>
            <strName>Gra - Base Model</strName>
            <intModelTypeID>1</intModelTypeID>          
            <totalVolumeTiersList>
                <totalVolumeTiers>
                    <decIncentiveRate>0.50</decIncentiveRate>
                    <decMaxValue>19.00</decMaxValue>
                    <decMinValue>0.00</decMinValue>                                 
                </totalVolumeTiers>             
            </totalVolumeTiersList>
        </rateModel>
        <rateModel>
            <intRateModelID>2</intRateModelID>
            <strName>Ges - Special</strName>
            <intModelTypeID>3</intModelTypeID>          
            <participationTiersList>
                <participationTiers>
                    <decIncentiveRate>0.50</decIncentiveRate>
                    <decMaxValue>19.00</decMaxValue>
                    <decMinValue>0.00</decMinValue>                                 
                </participationTiers>               
            </participationTiersList>
            <dollarBasedTiersList>
                <dollarBasedTiers>
                    <decIncentiveRate>0.50</decIncentiveRate>
                    <decMaxValue>19.00</decMaxValue>
                    <decMinValue>0.00</decMinValue>                             
                </dollarBasedTiers>             
            </dollarBasedTiersList>
        </rateModel>
        <rateModel>
            <intRateModelID>5</intRateModelID>
            <strName>G2 - participation</strName>
            <intModelTypeID>2</intModelTypeID>          
            <participationTiersList>
                <participationTiers>
                    <decIncentiveRate>0.50</decIncentiveRate>
                    <decMaxValue>19.00</decMaxValue>
                    <decMinValue>0.00</decMinValue>                 
                </participationTiers>               
            </participationTiersList>
        </rateModel>
    </rateModelList>

我想要的只是在单选查询中获取所有数据。

这是我的查询,但是没有按要求运作

Declare @planBean xml = '<rateModelList>
        <rateModel>
            <intRateModelID>1</intRateModelID>
            <strName>Gra - Base Model</strName>
            <intModelTypeID>1</intModelTypeID>          
            <totalVolumeTiersList>
                <totalVolumeTiers>
                    <decIncentiveRate>0.50</decIncentiveRate>
                    <decMaxValue>19.00</decMaxValue>
                    <decMinValue>0.00</decMinValue>                                 
                </totalVolumeTiers>             
            </totalVolumeTiersList>
        </rateModel>
        <rateModel>
            <intRateModelID>2</intRateModelID>
            <strName>G - Special</strName>
            <intModelTypeID>3</intModelTypeID>          
            <participationTiersList>
                <participationTiers>
                    <decIncentiveRate>0.50</decIncentiveRate>
                    <decMaxValue>19.00</decMaxValue>
                    <decMinValue>0.00</decMinValue>                                 
                </participationTiers>               
            </participationTiersList>
            <dollarBasedTiersList>
                <dollarBasedTiers>
                    <decIncentiveRate>0.50</decIncentiveRate>
                    <decMaxValue>19.00</decMaxValue>
                    <decMinValue>0.00</decMinValue>                             
                </dollarBasedTiers>             
            </dollarBasedTiersList>
        </rateModel>
        <rateModel>
            <intRateModelID>5</intRateModelID>
            <strName>Ges - participation</strName>
            <intModelTypeID>2</intModelTypeID>          
            <participationTiersList>
                <participationTiers>
                    <decIncentiveRate>0.50</decIncentiveRate>
                    <decMaxValue>19.00</decMaxValue>
                    <decMinValue>0.00</decMinValue>                 
                </participationTiers>               
            </participationTiersList>
        </rateModel>
    </rateModelList>'
SELECT 
      t.c.value('(strName/text())[1]', 'varchar(500)') as strName
    , t.c.value('(intModelTypeID/text())[1]', 'int') as intModelTypeID
    , s.c.value('(decMinValue/text())[1]', 'decimal(17,4)') as decMinValue_totalVolumeTiers
    , r.c.value('(decMinValue/text())[1]', 'decimal(17,4)') as decMinValue_participationTiers
    , u.c.value('(decMinValue/text())[1]', 'decimal(17,4)') as decMinValue_dollarBasedTiers
FROM @planBean.nodes('rateModelList/rateModel') t(c)
CROSS APPLY t.c.nodes('./totalVolumeTiersList/totalVolumeTiers') s(c)
CROSS APPLY t.c.nodes('./participationTiersList/participationTiers') r(c)
CROSS APPLY t.c.nodes('./dollarBasedTiersList/dollarBasedTiers') u(c)

结果必需

-------   --------------   -----------
strName | intModelTypeId | decMinValue
-------   --------------   -----------

2 个答案:

答案 0 :(得分:0)

您是否尝试使用OUTER APPLY而不是CROSS APPLY?

SELECT 
  t.c.value('(strName/text())[1]', 'varchar(500)') as strName
, t.c.value('(intModelTypeID/text())[1]', 'int') as intModelTypeID
, ( SELECT min(x) FROM ( VALUES (s.c.value('(decMinValue/text())[1]','decimal(17,4)')) , (r.c.value('(decMinValue/text())[1]','decimal(17,4)')) , (u.c.value('(decMinValue/text())[1]','decimal(17,4)')) ) AS val(x) ) as decMinValue
    FROM @planBean.nodes('rateModelList/rateModel') t(c)
    OUTER APPLY t.c.nodes('./totalVolumeTiersList/totalVolumeTiers') s(c)
    OUTER APPLY t.c.nodes('./participationTiersList/participationTiers') r(c)
    OUTER APPLY t.c.nodes('./dollarBasedTiersList/dollarBasedTiers') u(c)

否则,您可以使用三个查询的并集:

SELECT strName, intModelTypeID, min(decMinValue) decMinValue
    FROM
    (
    SELECT 
          t.c.value('(strName/text())[1]', 'varchar(500)') as strName
        , t.c.value('(intModelTypeID/text())[1]', 'int') as intModelTypeID
        , u.c.value('(decMinValue/text())[1]', 'decimal(17,4)') as decMinValue
    FROM @planBean.nodes('rateModelList/rateModel') t(c)
    CROSS APPLY t.c.nodes('./dollarBasedTiersList/dollarBasedTiers') u(c)
    UNION
    SELECT 
          t.c.value('(strName/text())[1]', 'varchar(500)') as strName
        , t.c.value('(intModelTypeID/text())[1]', 'int') as intModelTypeID
        , r.c.value('(decMinValue/text())[1]', 'decimal(17,4)') as decMinValue
    FROM @planBean.nodes('rateModelList/rateModel') t(c)
    CROSS APPLY t.c.nodes('./participationTiersList/participationTiers') r(c)
    UNION
    SELECT 
          t.c.value('(strName/text())[1]', 'varchar(500)') as strName
        , t.c.value('(intModelTypeID/text())[1]', 'int') as intModelTypeID
        , s.c.value('(decMinValue/text())[1]', 'decimal(17,4)') as decMinValue
    FROM @planBean.nodes('rateModelList/rateModel') t(c)
    CROSS APPLY t.c.nodes('./totalVolumeTiersList/totalVolumeTiers') s(c)
    ) sbt
    GROUP BY strName, intModelTypeID

只有在的数量减少和定义的情况下,这两种解决方案都是可行的。

答案 1 :(得分:0)

您可以在XQuery中使用通配符来访问decMinValue元素,也可以在XQuery中进行聚合。

select M.X.value('(strName/text())[1]', 'varchar(500)') as strName,
       M.X.value('(intModelTypeID/text())[1]', 'int') as intModelTypeID,
       M.X.value('min(*/*/decMinValue/text()) cast as xs:decimal?', 'decimal(17,4)') decMinValue
from @planBean.nodes('/rateModelList/rateModel') as M(X);

可以找到有关为什么存在xs:decimal的转换的解释here