计算XML节点中的每个元素,而不是连续计数

时间:2020-10-13 10:23:03

标签: sql sql-server xml tsql xquery

如何在计算SpelementUnit个元素的部分(SpelementElement_Count列)中改进此代码?

我需要一个SpelementUnit的序列计数,而不是整个XML中的连续计数。 (在每个EntitySpatial-> SpatialElement元素内)

这段代码从1到7。当我需要1,2-1,2,3-1,2

CODE

DECLARE @xml XML = 
N'<Parcels>
    <Parcel ID="1">
        <EntitySpatial>
            <SpatialElement>
                <SpelementUnit>
                    <Ordinate X="100.1" Y="-100.1"/>
                </SpelementUnit>
                <SpelementUnit>
                    <Ordinate X="100.2" Y="-100.2"/>
                </SpelementUnit>
            </SpatialElement>
            <SpatialElement>
                <SpelementUnit>
                    <Ordinate X="100.3" Y="-100.3"/>
                </SpelementUnit>
                <SpelementUnit>
                    <Ordinate X="100.4" Y="-100.4"/>
                </SpelementUnit>
                <SpelementUnit>
                    <Ordinate X="100.5" Y="-100.5"/>
                </SpelementUnit>
            </SpatialElement>
        </EntitySpatial>
    </Parcel>
    <Parcel ID="2">
        <EntitySpatial>
            <SpatialElement>
                <SpelementUnit>
                    <Ordinate X="200.1" Y="-200.1"/>
                </SpelementUnit>
                <SpelementUnit>
                    <Ordinate X="200.2" Y="-200.2"/>
                </SpelementUnit>
            </SpatialElement>
        </EntitySpatial>
    </Parcel>
</Parcels>';


SELECT base.value('@ID', 'VARCHAR(1000)') AS Parcel_ID
    , DENSE_RANK() OVER(ORDER BY outr) as SpatialElement_Count
--     ,outr2.value('@PointNum', 'NVARCHAR(1000)') AS PointNum
    ,outr2.value('(Ordinate/@X)[1]', 'NVARCHAR(1000)') AS Ordinate_X
    ,outr2.value('(Ordinate/@Y)[1]', 'NVARCHAR(1000)') AS Ordinate_Y
    , DENSE_RANK() OVER(ORDER BY outr2) as SpelementElement_Count 
FROM @xml.nodes('Parcels/Parcel') as x(base)
    OUTER APPLY base.nodes('EntitySpatial/SpatialElement') AS B(outr)
    OUTER APPLY outr.nodes('SpelementUnit') AS C(outr2);

所需的输出(主列为“ SpelementElement_Count”)

 +-----------+---------------------+-----  -----+------------+------------------------+
| Parcel_ID | SpatialElement_Count | Ordinate_X | Ordinate_Y | SpelementElement_Count |
+-----------+----------------------+------------+------------+------------------------+
|         1 |                    1 |      100.1 |     -100.1 |                      1 |
|         1 |                    1 |      100.2 |     -100.2 |                      2 |
|         1 |                    2 |      100.3 |     -100.3 |                      1 |
|         1 |                    2 |      100.4 |     -100.4 |                      2 |
|         1 |                    2 |      100.5 |     -100.5 |                      3 |
|         2 |                    3 |      200.1 |     -200.1 |                      1 |
|         2 |                    3 |      200.2 |     -200.2 |                      2 |
+-----------+----------------------+------------+------------+------------------------+

1 个答案:

答案 0 :(得分:2)

使用OVER子句时,可以使用PARTITION BY。简单

将查询结果集划分为多个分区。窗口功能是 分别应用于每个分区,并针对每个分区重新开始计算 分区。

您可以将PARTITION BY子句中的OVER视为使用聚合函数时的GROUP BY子句。

SELECT base.value('@ID', 'VARCHAR(1000)') AS Parcel_ID
    , DENSE_RANK() OVER(ORDER BY outr) as SpatialElement_Count
    ,outr2.value('(Ordinate/@X)[1]', 'NVARCHAR(1000)') AS Ordinate_X
    ,outr2.value('(Ordinate/@Y)[1]', 'NVARCHAR(1000)') AS Ordinate_Y
    , DENSE_RANK() OVER(PARTITION BY outr ORDER BY outr2) as SpelementElement_Count 
FROM @xml.nodes('Parcels/Parcel') as x(base)
    OUTER APPLY base.nodes('EntitySpatial/SpatialElement') AS B(outr)
    OUTER APPLY outr.nodes('SpelementUnit') AS C(outr2);