用于选择和分组的 XQuery

XQuery for selecting and grouping

我正在尝试从 xml 列中导出一些信息。

应用的逻辑: 在每个部分中,演员姓名可能会出现两次。 (演员 + 歌曲) 结果是一个独特的组合。

仅在聚合级别,场景=1 时保留。我们不关心 scene=2。 我们关心特定演员的台词。 辛巴、木法沙和沙祖。 我们不用担心疤痕。他很卑鄙。 我的预期输出是:

output

到目前为止我的 T-Sql 代码: 我已经设法过滤掉聚合级别 = 2.

有人可以帮忙吗?

DECLARE @Temp AS TABLE (Information xml)
INSERT INTO @Temp SELECT @x;
WITH XMLNAMESPACES ('lyceum' AS ns1)
SELECT
    Z.query('ns1:feature')
FROM @Temp
CROSS APPLY Information.nodes('/ns1:report/ns1:detail/ns1:parts/ns1:part') AS Y(Z)
WHERE Z.exist('ns1:aggregation[.="1"]') = 1

您可以在下面找到 xml 以便轻松重现:

DECLARE @x as xml;
set @x = '<ns1:report xmlns:ns1="lyceum">
    <ns1:header>
        <ns1:report>The Lion King</ns1:report>
    </ns1:header>
    <ns1:detail>
        <ns1:parts>
            <ns1:part>
                <ns1:aggregation>
                    <ns1:scene>1</ns1:scene>
                </ns1:aggregation>
                <ns1:feature>
                    <ns1:actor>Simba</ns1:actor>
                    <ns1:lines>100</ns1:lines>
                    <ns1:song>1</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Mufasa</ns1:actor>
                    <ns1:lines>200</ns1:lines>
                    <ns1:song>1</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Simba</ns1:actor>
                    <ns1:lines>300</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Zazu</ns1:actor>
                    <ns1:lines>400</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Scar</ns1:actor>
                    <ns1:lines>500</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
            </ns1:part>
            <ns1:part>
                <ns1:aggregation>
                    <ns1:scene>2</ns1:scene>
                </ns1:aggregation>
                <ns1:feature>
                    <ns1:actor>Simba</ns1:actor>
                    <ns1:lines>600</ns1:lines>
                    <ns1:song>1</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Mufasa</ns1:actor>
                    <ns1:lines>700</ns1:lines>
                    <ns1:song>1</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Simba</ns1:actor>
                    <ns1:lines>800</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Zazu</ns1:actor>
                    <ns1:lines>900</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Scar</ns1:actor>
                    <ns1:lines>1000</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
            </ns1:part>
        </ns1:parts>
    </ns1:detail>
</ns1:report>'

您正在向 select 和组请求 XQuery:试试这个:

一个模型table来模拟您的问题:

DECLARE @Temp AS TABLE (Information xml);
INSERT @Temp VALUES
('<ns1:report xmlns:ns1="lyceum">
    <ns1:header>
        <ns1:report>The Lion King</ns1:report>
    </ns1:header>
    <ns1:detail>
        <ns1:parts>
            <ns1:part>
                <ns1:aggregation>
                    <ns1:scene>1</ns1:scene>
                </ns1:aggregation>
                <ns1:feature>
                    <ns1:actor>Simba</ns1:actor>
                    <ns1:lines>100</ns1:lines>
                    <ns1:song>1</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Mufasa</ns1:actor>
                    <ns1:lines>200</ns1:lines>
                    <ns1:song>1</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Simba</ns1:actor>
                    <ns1:lines>300</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Zazu</ns1:actor>
                    <ns1:lines>400</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
                <ns1:feature>
                    <ns1:actor>Scar</ns1:actor>
                    <ns1:lines>500</ns1:lines>
                    <ns1:song>2</ns1:song>
                </ns1:feature>
            </ns1:part>
            <ns1:part>
                <ns1:aggregation>
                    <ns1:scene>2</ns1:scene>
                </ns1:aggregation>
                <ns1:feature>
<!-- shortened for brevity -->
                </ns1:feature>
            </ns1:part>
        </ns1:parts>
    </ns1:detail>
</ns1:report>');

--查询

WITH XMLNAMESPACES('lyceum' AS ns1)
SELECT p.query('<root>
                {
                    for $s in distinct-values(ns1:feature/ns1:song/text())
                    return <song scene="{$s}">
                        {
                        for $f in ns1:feature[ns1:song[text()=$s]]
                        return
                        if($f/ns1:actor/text() != "Scar") then
                            <actor name="{$f/ns1:actor/text()}" lines="{$f/ns1:lines/text()}"/>
                        else
                            ()
                        }
                    </song>
                }
                </root>')
  
FROM @Temp t
CROSS APPLY t.Information.nodes('/ns1:report/ns1:detail/ns1:parts/ns1:part[(ns1:aggregation/ns1:scene/text())[1]="1"]') A(p);

结果

<root>
  <song scene="1">
    <actor name="Simba" lines="100" />
    <actor name="Mufasa" lines="200" />
  </song>
  <song scene="2">
    <actor name="Simba" lines="300" />
    <actor name="Zazu" lines="400" />
  </song>
</root>

简而言之:

  • 我们将 .nodes() 中的谓词用于 return <scene>=1
  • 的部分
  • 我们使用.query()来return一个新创建的XML
  • 我们添加(可能省略)一个<root>节点
  • 我们通过不同的歌曲 ID 列表添加 FLWOR 查询运行
  • 我们在另一个 FLOWR 查询中使用此歌曲 ID 作为谓词来过滤拟合 <feature> 元素
  • 我们检查演员的名字是否不是“Scar”

您要求的输出是一个完全不同的问题。 使用 content 作为列名需要提前知道所有预期名称(PIVOT 条件聚合 )或使用动态创建的语句.