Pivoting previously xml data via SQL query throws error - sql

I have data in table as below where value column data is quite big, like unstructured text:
http://s3.pdfconvertonline.com/convert/p3r68-cdx67/78gbs-hvj2r.html
The characters which you find in date like &amp and &nbsp are present and this is just for 2 small records, actual data is quite bigger which is why i use pivot xml as the IDs are 300 in real data set.
The Heading and Value columns were initially HTML data for each ID which is now split on basis of heading and corresponding value in html using xmltype parsing.
Now we have data in the 2 columns split.
I need to pivot this, i.e. the Heading column values which are constant for ever id to become column headers and the respective values to come below as rows.
When I run the pivot query it throws error:
select *
from data
pivot xml (max(id) for heading in (select heading from data));
An error occurs in XML parsing.
Entity reference is not well formed.
XML Parser returned an error while trying to parse the document.
Check if document to be parsed is valid.
Could the error be because of these special characters?

Related

Handling Json data in snowflake

enter image description here
I have a table which contains Json file data in each row which gets updated into my snowflake table every weak. I am extracting values from the Json files into another table. When the data is loaded in Json format there are multiple entries of the same ID. So, when I extract values from Json to a table there are duplicate rows. How do I tackle them in order to get the distinct rows only. My select query look something like this:
select
json_data:data[0].attributes."Additional Invoice?":: string as "Additional Invoice?",
json_data:data[0].attributes."Additional PO?":: string as "Additional PO?",
json_data:data[0].attributes."Aggregate Contract Value":: number as "Aggreagate Contract Value" ,
json_data:data[0].attributes."Annualized Baseline Spend" :: number as "Annualized Baseline Spend",
json_data:data[0].id ::number as ID,
json_data:data[0].type::string as TYPE
from scout_projects order by ID
the scout project file screenshot is attached.
The attached Screenshot is the output form the given query and as you could see the ID column is the same but there are only 2 unique rows. I want my query to return only those 2 unique rows.
select distinct json_data:data[0].id :: number as ID from scout_projects
what is the approach should I take?
I tried using subquery, but it gave me error stating "single-row subquery returns more than one row. snowflake error" which is obvious. so, need a way out .

Converting SQL column with XML formatted text into a table

I have a XML data column in a SQL Server table. There are more than 5000 elements in the XML. I intended to make a table out of that XML formatted column.
As far as I'm aware, SQL has a limitation that a table can only have 1024 columns. How will I flatten the file so that it may be used for reporting?

How to convert generic XML to a table row in PostgreSQL?

PostgresSQL v12.5
There is a table with single column containing strings formatted as XML.
create table XMLDATA (value text);
--------
text
--------
<something> <a>uyt</a> <b>xyz</b> </something>
<something> <a>ryu</a> <b>sdg</b> </something>
For simplicity let's claim that there are no nesting: all tags inside <something> contain primitive values (strings).
Assuming that there are much more elements than <a> and <b> inside, it would be great to have an option to convert these values into a relational form without enumerating all of the nested tags manually.
Was trying to get something in documentation related to XPATH, XMLTABLE, XPATH_TABLE, but there are small number of examples that did not help me to reveal the full power of these functions.
What I am looking for is a function special_function with results like
select * from special_function(XMLDATA);
a | b
-----------
uyt | xyz
ryu | sdg
Could you help me find a functionality of PostgreSQL that automatically recognizes XML tags and convert their content into columns?
without enumerating all of the nested tags manually.
That's not possible.
One fundamental restriction of SQL is, that the number, data types and names of all columns need to be known to the database before the query starts executing. SQL can't do this "at runtime" and change structure of the query based on data that is retrieved.
You can extract the content using xmltable() - but as explained, there is no way without specifying each output column.
select x.*
from xmldata d
cross join xmltable('/something' passing d.value
columns a text path 'a',
b text path 'b') as x
This assumes value is declared with the data type xml (which it should be). If it's not the case, you need to cast it: passing d.value::xml

SQL. XML values from column. How to get?

For example I have table "BigApple" with three columns.
first column includes numbers
second column includes some text
third column includes XML files.
My question is: how to get to the third column of the specific values for a particular tag?
Use one of the XML methods on XML column https://msdn.microsoft.com/en-us/library/ms190798.aspx
In fact, if you have the same kind of XML data in the third column you can read specific tag values easily.
Please refer to examples on SQL XML query using a single XML variable
and example to query XML column in SQL database table using CROSS APPLY
Mao, how do you expect to get an answer which really helps you without showing your data? It can be trivial 'til really tricky to get data from an XML. Do you need only one particular tag? Or are there several data? Nested data?
One example for a trivial read might be this:
CREATE TABLE #tmpTbl(Number INT, SomeText VARCHAR(100),SomeXML XML);
INSERT INTO #tmpTbl VALUES
(1,'Test1','<root><a>xmlA1</a><b>xmlB1</b></root>')
,(2,'Test2','<root><a>xmlA2</a><b>xmlB2</b></root>');
SELECT Number
,SomeText
,SomeXML.value('(/root/a)[1]','varchar(10)') AS Tag_a
FROM #tmpTbl;
GO
DROP TABLE #tmpTbl;
The result
Number SomeText Tag_a
1 Test1 xmlA1
2 Test2 xmlA2

Compare XML data to String

I have a table that houses a bunch of data in an XML field. I can get to the data and display what I need in the select statement, but I also need to use that to compare to another table that houses a translation I am trying to do. Is there a way to compare the value being returned from the XML data to a string value that exists in another table?
The code in my select to return the XML data is:
prv.reported_attributes.value('(/row[#ATTRIBUTE="FIELD"][1])/#VALUE', 'varchar(5)')
I need to compare that text output to another table, but I keep getting NULL like the values I am trying to compare do not match. I have confirmed they do in fact have matches.