Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count each element within XML node instead of continuous counting

How to improve this code in the part where the number of SpelementUnit elements are counted (SpelementElement_Count column)?

Instead of a continuous counting within the entire XML I need a SpelementUnit's sequences count separately. (Inside each EntitySpatial--> SpatialElement elements)

While this code counts from 1 to 7. When i need like 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);

Desired output (main column is "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 |
+-----------+----------------------+------------+------------+------------------------+
like image 925
XSLT-explorer Avatar asked Feb 23 '26 15:02

XSLT-explorer


1 Answers

You can use PARTITION BY when OVER clause is used. It simply

Divides the query result set into partitions. The window function is applied to each partition separately and computation restarts for each partition.

You can think for PARTITION BY in OVER clause, as GROUP BY clause when aggregate function is used.

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);
like image 152
gotqn Avatar answered Feb 26 '26 09:02

gotqn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!