Iterate Over Many XML Attributes In SQL - sql

I have a XML file that has a series of attributes. The attributes look something like the list below:
<Summary>
<MyAttributes AT001="ABC" AT002="123" AT003="456" AT004="DEF" ... />
</Summary>
I need to iterate over the attributes and add them into a SQL table that looks something like this:
Name
Value
AT001
ABC
AT002
123
AT003
456
AT004
DEF
...
...
Because the attribute list isn't fixed, I need to iterate over all the attributes to ensure each attribute gets added.
I typically can figure out how to do things in SQL, but this one has me stumped!

It is not clear what SQL you are using.
Here is how to do it in MS SQL Server by using its T-SQL and XQuery methods.
SQL
DECLARE #xml XML =
N'<Summary>
<MyAttributes AT001="ABC" AT002="123" AT003="456" AT004="DEF" />
</Summary>';
SELECT c.value('local-name(.)', 'VARCHAR(30)') AS attr_name
, c.value('.', 'VARCHAR(30)') AS attr_value
FROM #xml.nodes('/Summary/MyAttributes/#*') AS t(c);
Output
+-----------+------------+
| attr_name | attr_value |
+-----------+------------+
| AT001 | ABC |
| AT002 | 123 |
| AT003 | 456 |
| AT004 | DEF |
+-----------+------------+

Related

How to get a value inside of a JSON that is inside a column in a table in Oracle sql?

Suppose that I have a table named agents_timesheet that having a structure like this:
ID | name | health_check_record | date | clock_in | clock_out
---------------------------------------------------------------------------------------------------------
1 | AAA | {"mental":{"stress":"no", "depression":"no"}, | 6-Dec-2021 | 08:25:07 |
| | "physical":{"other_symptoms":"headache", "flu":"no"}} | | |
---------------------------------------------------------------------------------------------------------
2 | BBB | {"mental":{"stress":"no", "depression":"no"}, | 6-Dec-2021 | 08:26:12 |
| | "physical":{"other_symptoms":"no", "flu":"yes"}} | | |
---------------------------------------------------------------------------------------------------------
3 | CCC | {"mental":{"stress":"no", "depression":"severe"}, | 6-Dec-2021 | 08:27:12 |
| | "physical":{"other_symptoms":"cancer", "flu":"yes"}} | | |
Now I need to get all agents having flu at the day. As for getting the flu from a single JSON in Oracle SQL, I can already get it by this SQL statement:
SELECT * FROM JSON_TABLE(
'{"mental":{"stress":"no", "depression":"no"}, "physical":{"fever":"no", "flu":"yes"}}', '$'
COLUMNS (fever VARCHAR(2) PATH '$.physical.flu')
);
As for getting the values from the column health_check_record, I can get it by utilizing the SELECT statement.
But How to get the values of flu in the JSON in the health_check_record of that table?
Additional question
Based on the table, how can I retrieve full list of other_symptoms, then it will get me this kind of output:
ID | name | other_symptoms
-------------------------------
1 | AAA | headache
2 | BBB | no
3 | CCC | cancer
You can use JSON_EXISTS() function.
SELECT *
FROM agents_timesheet
WHERE JSON_EXISTS(health_check_record, '$.physical.flu == "yes"');
There is also "plain old way" without JSON parsing only treting column like a standard VARCHAR one. This way will not work in 100% of cases, but if you have the data in the same way like you described it might be sufficient.
SELECT *
FROM agents_timesheet
WHERE health_check_record LIKE '%"flu":"yes"%';
How to get the values of flu in the JSON in the health_check_record of that table?
From Oracle 12, to get the values you can use JSON_TABLE with a correlated CROSS JOIN to the table:
SELECT a.id,
a.name,
j.*,
a."DATE",
a.clock_in,
a.clock_out
FROM agents_timesheet a
CROSS JOIN JSON_TABLE(
a.health_check_record,
'$'
COLUMNS (
mental_stress VARCHAR2(3) PATH '$.mental.stress',
mental_depression VARCHAR2(3) PATH '$.mental.depression',
physical_fever VARCHAR2(3) PATH '$.physical.fever',
physical_flu VARCHAR2(3) PATH '$.physical.flu'
)
) j
WHERE physical_flu = 'yes';
db<>fiddle here
You can use "dot notation" to access data from a JSON column. Like this:
select "DATE", id, name
from agents_timesheet t
where t.health_check_record.physical.flu = 'yes'
;
DATE ID NAME
----------- --- ----
06-DEC-2021 2 BBB
Note that this approach requires that you use an alias for the table name (so you can use it in accessing the JSON data).
For testing I used the data posted by MT0 on dbfiddle. I am not a big fan of double-quoted column names; use something else for "DATE", such as dt or date_.

HIVE SQL: Select rows whose values contain string in a column

I want to select rows whose values contain a string in a column.
For example, I want to select all rows whose values contain a string '123' in the column 'app'.
table:
app id
123helper xdas
323helper fafd
2123helper dsaa
3123helper fafd
md5321 asdx
md5123 dsad
result:
app id
123helper xdas
2123helper dsaa
3123helper fafd
md5123 dsad
I am not familiar with SQL query.
Could anyone help me? .
Thanks in advances.
In a number of ways:
like:
select * from table
where app like '%123%'
rlike:
...
where app rlike '123'
instr:
...
where instr(app, '123')>0
locate:
...
where locate('123', app)>0
Invent your own way.
Read manual: String Functions and Operators.
Try the following using like
select
*
from yourTable
where app like '%123%'
Output:
| app | id |
| ---------- | ---- |
| 123helper | xdas |
| 2123helper | dsaa |
| 3123helper | fafd |
| md5123 | dsad |
Please use below query,
select app, id from table where app like '%123%';
Below are few additional information,
like '123%' --> Starts with 123
like '%123' --> Ends with 123
like '%123%'--> Contains 123 anywhere in the string

Return an array(Repeated Field) from a query in BigQuery

I am new to BigQuery and SQL. I have a table with following details
Schema
ID : String : Nullable
BCats : String : Repeated
ID can be repeated
Preview
ID BCats
|-----------------------|
| ABCD | BCat25 |
| | BCat24 |
| | BCat23 |
|_______________________|
| PQRS | BCat8 |
| | BCat9 |
|_______________________|
| ABCD | BCat23 |
| | BCat25 |
| | BCat24 |
|_______________________|
| MNOP | BCat12 |
| | BCat13 |
|_______________________|
| PQRS | BCat8 |
| | BCat9 |
|-----------------------|
I am trying to group the table based on ID using the following query
Query
SELECT BCats,ID
FROM (SELECT (GROUP_CONCAT(BCats)) as BCats,ID
FROM(
SELECT
UNIQUE(BCats) as BCats,ID FROM
my_table
GROUP BY
ID
)
GROUP BY
ID
)
OUTPUT from the query in JSON Format is
Output from Query
{"BCats":"BCat25,BCat24,BCat23","ID":"ABCD"}
{"BCats":"BCat8,BCat9","ID":"PQRS"}
{"BCats":"BCat12,BCat13","ID":"MNOP"}
My question is how can I output Array from the Query, like this
Expecting Output
{"BCats" : ["BCat25","BCat24","BCat23"],"ID":"ABCD"}
Currently I am getting BCats as a String.
I need to output this data into new table with BCats as Repeated.
Please Help.
Preview :
Try below. Note: in Web UI you need not only set Destination Table but also set/check-on Allow Large Results checkbox and uncheck Flatten Results checkbox
SELECT NEST(UNIQUE(BCats)) AS BCats, ID
FROM my_table
GROUP BY ID
You should instead use standard SQL. If you are familiar with legacy SQL, there is a migration guide that talks about the differences between the two dialects. After enabling standard SQL (uncheck "Use Legacy SQL" under "Show Options" in the UI) you can run e.g.:
WITH my_table AS (
SELECT 'ABCD' AS ID, ['BCat25', 'BCat24', 'BCat23'] AS BCats UNION ALL
SELECT 'PQRS', ['BCat8', 'BCat9'] UNION ALL
SELECT 'ABCD', ['BCat23', 'BCat25', 'BCat24'] UNION ALL
SELECT 'MNOP', ['BCat12', 'BCat13'] UNION ALL
SELECT 'PQRS', ['BCat8', 'BCat9']
)
SELECT
ID,
ARRAY_AGG(DISTINCT BCat) AS BCats
FROM my_table, UNNEST(BCats) AS BCat
GROUP BY ID;

SQL query to format table data for DataSource in GridView

I am looking for a SQL Server query that could transfer source SQL table data:
TextID | Text | LanguageID
-------|-------|-------------------------------------
app.aa | Hi | 6a13ea09-46ea-4c93-9b6a-e26bdc6ff4d8
app.cc | Hund | 0c894bb7-4937-4903-906a-d1b1dd64935c
app.aa | Hallo | 0c894bb7-4937-4903-906a-d1b1dd64935c
app.cc | Dog | 6a13ea09-46ea-4c93-9b6a-e26bdc6ff4d8
app.bb | Star | 6a13ea09-46ea-4c93-9b6a-e26bdc6ff4d8
...
into table like this one:
TextID | Original | Translated
-------|----------|-----------
app.aa | Hi | Hallo
app.bb | Star | -
app.cc | Dog | Hund
...
so that I can use it as a DataSource for GridView in ASP .NET. Thank you in advance for your help.
Whenever you need to combine data from two different rows into one, you need to join. For example:
select src.TextID "TextID", src.Text "Original", tr.Text "Translated"
from source_table src
left join source_table tr
on src.TextID = tr.TextID
and src.LangID = 'xxx' -- xxx is the source language id
and tr.LangID = 'yyy' -- yyy is the target language id
The left join ensures that untranslated words are included with a null translated value. To make a table for your DataSource, you'll need to wrap create table (or maybe create view) around the select:
create table translations as
select ...

Query XML File uploaded to single column in SQL Server

I am trying to learn XQuery and Xpath in SQL Server
I created a sample file and uploaded it to a Table with 2 columns ID, XMLDoc. The below code is within the document in the XMLDoc column so it is the only record in the column.
I am trying to query the file so it will show all the results in a table like a normal select statement would. How would you construct the select statement to select all the information like a select * ? How would you select one field like all suppliers? I would like to select the supplier, requestor for each item.
Here is the xml:
<tst:Document xmlns:tst ="http://www.w3.org/2001/XMLSchema" SchemaVersion="0.1" Classification="Test" UniqueIdentifier="1234" Title="Test">
<tst:Revision RevNumber="0" TimeStamp="2013-01-21T12:56:00">
<tst:Author Name="Me" Guid="1234" />
</tst:Revision>
<tst:Formats>
<tst:A12 Item="1">
<tst:Requestor Name="ADC" />
<tst:Supplier Name="BBC" />
<tst:Code>B</tst:Code>
<tst:IsRequirement>true</tst:IsRequirement>
<tst:IsNotRequired>false</tst:IsInformation>
<tst:Remarks>ADC (Random Input Section)</tst:Remarks>
<tst:Notes>Next Round.</tst:Notes>
<tst:Events>
<tst:SubTest Item="0">
<tst:BLDG>BLDG1</tst:BLDG>
<tst:BLDG2>BLDG2</tst:BLDG2>
<tst:Function>Testing</tst:Function>
<tst:Desciption>Normal Flow</tst:Desciption>
</tst:SubTest>
</tst:Events>
<tst:IsReady>true</tst:IsReady>
<tst:IsNotReady>false</tst:IsNotReady>
</tst:A12>
<tst:A12 Item="2">
<tst:Requestor Name="ADC" />
<tst:Supplier Name="BBC" />
<tst:Code>A</tst:Code>
<tst:IsRequirement>true</tst:IsRequirement>
<tst:IsInformation>false</tst:IsInformation>
<tst:Remarks>Requirement Not yet met.</tst:Remarks>
<tst:Notes>Ready.</tst:Notes>
<tst:Events>
<tst:SubTest Item="0">
<tst:BLDG>BLDG3</tst:BLDG>
<tst:BLDG2>BLDG4</tst:BLDG2>
<tst:TotalEvents>1</tst:TotalEvents>
<tst:Function>Development</tst:Function>
<tst:Desciption>Process Flow</tst:Desciption>
</tst:SubTest>
</tst:Events>
<tst:IsReady>true</tst:IsReady>
<tst:IsNotReady>false</tst:IsNotReady>
</tst:A12>
</tst:Formats>
</tst:Document>
Query I ran
I just got a return, but it is still showing it in xml form:
Select XMLDoc.query('/*/*/*/*[local-name()=("Requestor", "Supplier")]')
From XMLLoad
I Updated the xml snippet, sry had a typo! It will load now
INSERT INTO TableName(ColumnName)
SELECT * FROM OPENROWSET(
BULK 'C:\Users\Filepath.xml',
SINGLE_BLOB) AS x;
SQL Fiddle
MS SQL Server 2008 Schema Setup:
create table XMLDoc (XMLLoad xml);
insert into XMLDoc(XMLLoad) values('
<tst:Document xmlns:tst ="http://www.w3.org/2001/XMLSchema" SchemaVersion="0.1" Classification="Test" UniqueIdentifier="1234" Title="Test">
<tst:Revision RevNumber="0" TimeStamp="2013-01-21T12:56:00">
<tst:Author Name="Me" Guid="1234" />
</tst:Revision>
<tst:Formats>
<tst:A12 Item="1">
<tst:Requestor Name="ADC" />
<tst:Supplier Name="BBC" />
<tst:Code>B</tst:Code>
<tst:IsRequirement>true</tst:IsRequirement>
<tst:IsInformation>false</tst:IsInformation>
<tst:Remarks>ADC (Random Input Section)</tst:Remarks>
<tst:Notes>Next Round.</tst:Notes>
<tst:Events>
<tst:SubTest Item="0">
<tst:BLDG>BLDG1</tst:BLDG>
<tst:BLDG2>BLDG2</tst:BLDG2>
<tst:Function>Testing</tst:Function>
<tst:Desciption>Normal Flow</tst:Desciption>
</tst:SubTest>
</tst:Events>
<tst:IsReady>true</tst:IsReady>
<tst:IsNotReady>false</tst:IsNotReady>
</tst:A12>
<tst:A12 Item="2">
<tst:Requestor Name="ADC" />
<tst:Supplier Name="BBC" />
<tst:Code>A</tst:Code>
<tst:IsRequirement>true</tst:IsRequirement>
<tst:IsInformation>false</tst:IsInformation>
<tst:Remarks>Requirement Not yet met.</tst:Remarks>
<tst:Notes>Ready.</tst:Notes>
<tst:Events>
<tst:SubTest Item="0">
<tst:BLDG>BLDG3</tst:BLDG>
<tst:BLDG2>BLDG4</tst:BLDG2>
<tst:TotalEvents>1</tst:TotalEvents>
<tst:Function>Development</tst:Function>
<tst:Desciption>Process Flow</tst:Desciption>
</tst:SubTest>
</tst:Events>
<tst:IsReady>true</tst:IsReady>
<tst:IsNotReady>false</tst:IsNotReady>
</tst:A12>
</tst:Formats>
</tst:Document>');
Query 1:
with xmlnamespaces('http://www.w3.org/2001/XMLSchema' as tst)
select A12.X.value('#Item', 'int') as A12,
A12.X.value('tst:Requestor[1]/#Name', 'varchar(25)') as Requestor,
A12.X.value('tst:Supplier[1]/#Name', 'varchar(25)') as Supplier,
A12.X.value('(tst:Code/text())[1]', 'varchar(25)') as Code,
A12.X.value('(tst:IsRequirement/text())[1]', 'bit') as IsRequirement,
A12.X.value('(tst:IsInformation/text())[1]', 'bit') as IsInformation,
A12.X.value('(tst:Remarks/text())[1]', 'varchar(50)') as Remarks,
A12.X.value('(tst:Notes/text())[1]', 'varchar(50)') as Notes,
ST.X.value('#Item', 'int') as SubTest,
ST.X.value('(tst:BLDG/text())[1]', 'varchar(25)') as BLDG,
ST.X.value('(tst:BLDG2/text())[1]', 'varchar(25)') as BLDG2,
ST.X.value('(tst:TotalEvents/text())[1]', 'int') as TotalEvents,
ST.X.value('(tst:Function/text())[1]', 'varchar(25)') as [Function],
ST.X.value('(tst:Desciption/text())[1]', 'varchar(50)') as Desciption
from XMLDoc as X
cross apply X.XMLLoad.nodes('/tst:Document/tst:Formats/tst:A12') as A12(X)
cross apply A12.X.nodes('tst:Events/tst:SubTest') as ST(X)
Results:
| A12 | REQUESTOR | SUPPLIER | CODE | ISREQUIREMENT | ISINFORMATION | REMARKS | NOTES | SUBTEST | BLDG | BLDG2 | TOTALEVENTS | FUNCTION | DESCIPTION |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | ADC | BBC | B | 1 | 0 | ADC (Random Input Section) | Next Round. | 0 | BLDG1 | BLDG2 | (null) | Testing | Normal Flow |
| 2 | ADC | BBC | A | 1 | 0 | Requirement Not yet met. | Ready. | 0 | BLDG3 | BLDG4 | 1 | Development | Process Flow |
Check out value() and nodes().