Elen
Elen

Reputation: 2343

SQL Server parse XML column to get a column value if other column value equals certain value

In SQL Server 2014 a table with a CustomColumns column that contains XML data with the following structure:

<CustomColumnsCollection>
  <CustomColumn>
    <Name>Brand</Name>
    <DataType>0</DataType>
    <Value>Duprim</Value>
  </CustomColumn>
  <CustomColumn>
    <Name>LabelGroup</Name>
    <DataType>0</DataType>
    <Value />
  </CustomColumn>
...
</CustomColumnsCollection>

I want to get value of column Value where column Name equals, i.e. 'Brand' (the following code is a part of bigger query, which I saved as VIEW):

MAX(DISTINCT PR.CustomColumns.value('(/CustomColumnsCollection/CustomColumn/Name="Brand"/Value)[0]', 'varchar(max)')) AS Brand

In this case I would like it to return 'Duprim'. How is this achieved?

Upvotes: 0

Views: 736

Answers (2)

Yitzhak Khabinsky
Yitzhak Khabinsky

Reputation: 22177

Here is another method by using XPath predicate.

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, CustomColumns XML);
INSERT INTO @tbl (CustomColumns)
VALUES
(N'<CustomColumnsCollection>
    <CustomColumn>
        <Name>Brand</Name>
        <DataType>0</DataType>
        <Value>Duprim</Value>
    </CustomColumn>
    <CustomColumn>
        <Name>LabelGroup</Name>
        <DataType>0</DataType>
        <Value/>
    </CustomColumn>
</CustomColumnsCollection>');
-- DDL and sample data population, end

DECLARE @param VARCHAR(30) = 'Brand';

SELECT  ID
    , c.value('(Value/text())[1]', 'VARCHAR(50)') AS [Value]
FROM @tbl
    CROSS APPLY CustomColumns.nodes('/CustomColumnsCollection/CustomColumn[(Name/text())[1] eq sql:variable("@param")]') AS t(c);

-- hard-coded value
SELECT  ID
    , c.value('(Value/text())[1]', 'VARCHAR(50)') AS [Value]
FROM @tbl
    CROSS APPLY CustomColumns.nodes('/CustomColumnsCollection/CustomColumn[(Name/text())[1] eq "Brand"]') AS t(c);

Output

+----+--------+
| ID | Value  |
+----+--------+
|  1 | Duprim |
+----+--------+

To help you with the view that is consumed by the MS Excel. It would be great if you could provide a minimal reproducible example: (1) DDL and sample data population, i.e. CREATE table(s) plus INSERT, T-SQL statements. (2) What you need to do, i.e. logic. (3) Desired output based on the sample data in #1 above.

SQL for Excel

SELECT ID
    , CustomColumns.value('(/CustomColumnsCollection/CustomColumn[(Name/text())[1] eq "Brand"]/Value/text())[1]', 'VARCHAR(50)') AS [Value]
FROM @tbl;

Upvotes: 2

marc_s
marc_s

Reputation: 754468

Try something like this:

SELECT
    xc.value('(Value)[1]', 'varchar(50)') 
FROM
    PR
CROSS APPLY
    PR.CustomColumns.nodes('/CustomColumnsCollection/CustomColumn') AS XT(XC)
WHERE   
    xc.value('(Name)[1]', 'varchar(50)') = 'Brand'

The .nodes() returns a list of XML fragments, each representing a <CustomColumn> node. Select the one with the Name value of Brand in the WHERE clause, and get the value of Value for that XML node

Upvotes: 0

Related Questions