XML & YQL (similar to SQL) - how to get a subnode's attribute? - sql

I'm trying to select a certain set of data with YQL, but I'm confused on how to get to sublevels with my YQL. For example, if I run this query:
select * from music.track.search where keyword="Asia"
I get this:
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:count="22" yahoo:created="2011-07-07T16:47:41Z" yahoo:lang="en-US">
<results>
<Track discNumber="1" duration="0" explicit="0" flags="0"
id="61642071" label="Mark Saliba" popularity="3" rating="-1"
releaseYear="2008" rights="2208" title="Asia"
trackNumber="3" url="http://new.music.yahoo.com/mark-j-saliba/tracks/asia--61642071">
<Artist catzillaID="0" flags="2" hotzillaID="0"
id="205843271" name="Mark J Saliba" rating="-1"
trackCount="11"
url="http://new.music.yahoo.com/mark-j-saliba/" website=""/>
<Album>
and if I run this query:
select ID from music.track.search where keyword="Asia"
I get this:
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
yahoo:count="22" yahoo:created="2011-07-07T16:50:13Z" yahoo:lang="en-US">
<results>
<Track id="61642071"/>...
But what I want to do is just get the artist IDs, not the track IDs (specifically, just the first result would be fine). What is the YQL statement for that?

For all artist ids:
select Artist.id from music.track.search where keyword="Asia"
For just the first artist id:
select Artist.id from music.track.search where keyword="Asia" limit 1

Related

T-SQL, get value from xml in a column

I have a table with an XML column (xmlCol) and I am trying to query a value from it.
Here's the xml.
<criteria>
<factor name="Rivers" title="Rivers">
<value dataType="Int32" value="1743" description="Wilson0" />
</factor>
<factor name="OptionalAffProperties" title="Include properties">
<value dataType="String" value="FishingModel" description="Fishing Model" />
</factor>
</criteria>
Here is a select to get the column. select xmlCol from MyTable
I am trying to return the value 1743 to a column called RiverID.
Mike
This should work:
SELECT
xmlCol.value('(//factor[#name="Rivers"]/value/#value)[1]', 'int') As RiverID
FROM
MyTable
value() Method (xml Data Type) - SQL Server | Microsoft Docs
XQuery Language Reference (SQL Server) - SQL Server | Microsoft Docs
To get the attribute value, you can query it like so:
select xmlCol.value('(/criteria/factor/value/#value)[1]', 'int') RiverID
from MyTable
You provide the xml path to the record you are looking for: (/criteria/factor/value
And then the attribute you need: /#value)[1].

Concat xml node values in MS SQL

I need to get the childnode values of users with multiple keys, as shown below:
<Individuals>
<User key="0">
<UserlID>100</UserlID>
<FirstName>John Doe</FirstName>
</User>
<User key="1">
<UserlID>101</UserlID>
<FirstName>Jane Doe</FirstName>
</User>
<User key="2">
<UserlID>102</UserlID>
<FirstName>Jack Black</FirstName>
</User>
</Individuals>
My desired result will be either, three rows of all key-s UserID-s or one row concatenating all three key UserID-s. the number of the key is variable, maybe more than three.
Have managed to get static UserID values:
SELECT
[UserID] = A.XmlField.value('(Individuals/User[#key=2]/UserlID)[1]', 'Int')
FROM [MyTable] As A
but the problem is I cannot get all the userID-s
You can do it this way:
SELECT u.value('UserlID[1]', 'int') as UserlID
FROM MyTable CROSS APPLY XmlField.nodes('/Individuals/User') i(u)

SSRS - Conditionally select elements from XML data source

I have a simple XML tree:
<manufacturer = 'Audi'>
<make = 'A4'>
<color>Black</color>
<build_date>11th May 2014</build_date>
</make>
</manufacturer>
I know I can query data using:
<Query>
<ElementPath>
manufacturer{}/make{color, build_date}
</ElementPath>
</Query>
What I'd like to do is filter the results using the date attribute. Like a SQL WHERE clause. So in this example it's cars that are built after a specified date. Is this possible?
You would need set a filter on the data set in SSRS on the Build_date Field:
http://msdn.microsoft.com/en-us/library/dd255287.aspx
Yes you can filter the result from an xml. An example to your query is as below
SELECT
[xmlField].value('(/person//firstName/node())[1]', 'nvarchar(max)') as FirstName,
[xmlField].value('(/person//lastName/node())[1]', 'nvarchar(max)') as LastName
FROM [myTable]

Extracting child node value from XML using T-SQL

I'm stuck on trying to get the 'availability' node's value out of an envelope returned via T-SQL from a Microsoft Lync database. The usual methods of .value('(/MyElement/Something)[1]') doesn't seem to work for me.
<state xsi:type="aggregateState" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2006/09/sip/state">
<availability>3500
</availability>
<delimiter xmlns="http://schemas.microsoft.com/2006/09/sip/commontypes" />
<timeZoneBias>-60
</timeZoneBias>
<timeZoneName>GMT Daylight Time
</timeZoneName>
<timeZoneAbbreviation>GMT Daylight Time
</timeZoneAbbreviation>
<device>computer
</device>
<end xmlns="http://schemas.microsoft.com/2006/09/sip/commontypes" />
</state>
This is the query I've been experimenting with:
SELECT TOP 1
CAST(SUBSTRING(i.Data, 0, 4000) as XML).value('(/state//availability)[1]', 'varchar(256)')
FROM dbo.PublishedCategoryInstanceView AS i
INNER JOIN dbo.CategoryDef AS d
ON (d.CategoryId = i.CategoryId)
WHERE i.PublisherId = (SELECT ResourceId FROM dbo.Resource
WHERE UserAtHost = 'my.email#mydomain.local')
ORDER BY i.LastPubTime DESC
All I get back is 'NULL' unless I do CAST(SUBSTRING(i.Data, 0, 4000) as XML).value('(/)[1]', 'varchar(256)') which returns 3500-60GMT Daylight TimeGMT Daylight Timecomputer
I do know that when I strip out the three attributes on the state element I can perform normal XML queries against the data so I can get around this by manipulating the string with a few replace statements but I'd rather learn exactly what I'm doing wrong here, if anyone can help?
You're just plain ignoring the XML namespace that exists on your XML root node:
<state xsi:type="aggregateState"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.microsoft.com/2006/09/sip/state">
******************************************************
You need to include that in your T-SQL query!
Try something like this:
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/2006/09/sip/state')
SELECT TOP 1
CAST(SUBSTRING(i.Data, 0, 4000) as XML).value('(/state//availability)[1]', 'varchar(256)')
FROM
dbo.PublishedCategoryInstanceView AS i

Finding the relevant records using XQuery/XPath

I'm very very new to XQUERY/XPATH :) so I could very well be going about this the wrong way. I have a customer object serialized and stored in a database column in the following format.
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Addresses>
<AddressBlock>
<AddressLine1>1234 SomeStreet Ave.</AddressLine1>
<City>SomeCity</City>
<State>SomeState</State>
<Zipcode>SomeZip</Zipcode>
</AddressBlock>
<AddressBlock>
<AddressLine1>5678 SomeOtherStreet Ave.</AddressLine1>
<City>SomeOtherCity</City>
<State>SomeOtherState</State>
<Zipcode>SomeOtherZip</Zipcode>
</AddressBlock>
</Addresses>
</Customer>
I'm looking for a way to select this record if addressline1 and city in the same addressblock contains certain keywords. I have the following statement that almost does what I'm looking for.
select *
from users
where [UserData].exist('/Customer/Addresses/AddressBlock/AddressLine1/text()[contains(upper-case(.),""SOMESTREET"")]')=1
and [UserData].exist('/Customer/Addresses/AddressBlock/City/text()[contains(upper-case(.),""SOMECITY"")]')=1"
My only problem is this statment will also return the record if the first addressblock contains the addressline1 and the second addressblock contains the city.
You have to test both conditions in the same XQuery.
select *
from users
where [UserData].exist('/Customer/Addresses/AddressBlock
[contains(upper-case(AddressLine1[1]),"SOMESTREET") and
contains(upper-case(City[1]),"SOMECITY")]')=1