Get value from specific xml name value pair using sql - sql

I am writing a query in SQL to combine a few tables of data and have got to one where it is stored in XML in the following format:
<CustomDetails xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Fields>
<Field>
<Name>Selected City</Name>
<Value>Central</Value>
</Field>
<Field>
<Name>Address Provided</Name>
<Value>New Address</Value>
</Field>
</Fields>
</CustomDetails>
The XML is stored in a table and I have managed to get the Address Provided field using the following code
select
o.OrderID,
od.CustomDetails.query('data(/CustomDetails/Fields/Field[2]/Value)') as 'Address Provided'
from
dbo.[Order] o on
o.OrderID = s.OrderID
join
dbo.OrderData od on
od.OrderID = o.OrderID
I would like to know if there is a better way of doing this and also if there is a way to guarantee that I will get the Address Provided field even if it appears first or if there are other fields in front of it.
Hopefully that all makes sense, Any help is appreciated.
Thanks

After some research I managed to get a solution.
select
o.OrderID,
cast(od.CustomDetails.query('
for $CD in /CustomDetails/Fields/Field,
$Name in $CD/Name
where contains($Name, "Address Provided")
return data($CD/Value)
') as varchar(50)) as addressProvided
from
dbo.[Order] o on
o.OrderID = s.OrderID
join
dbo.OrderData od on
od.OrderID = o.OrderID

Related

How to convert and optimize this SQL query in SqlKata

I have this SQL query and I need to convert it SqlKata
SELECT VVIAGGIO AS VIAGGIO, ISNULL(AEAN,'') AS EAN
FROM
SALDI V INNER JOIN ARTICOLI A ON VARTI=AARTI
INNER JOIN ORDI OT ON VSTAB=OTSTAB AND VMAGA=OTMAGA AND VAGG=OTRAGG
WHERE VORDI ='21'
AND VHOST ='68'
ORDER BY VPROG, AARTI
I don't know how to structure it because here is ISNULL(), INNER JOIN..
I already checked SqlKata select instruction.
Any suggestions on how to optimize and convert this query in SqlKata?
here is what you need:
var query = new Query("SALDI as V")
.Join("ARTICOLI as A","A.ARTI","V.ARTI")
.Join("ORDI as OT",j => j.On("OT.STAB","V.STAB")
.On("V.MAGA","OT.MAGA")
.On("V.AGG","OT.RAGG")
)
.Where("V.ORDI","21")
.Where("V.HOST","68")
.Select("V.VIAGGIO")
.SelectRaw("ISNULL(V.AEAN,'') as EAN")
.OrderBy("V.PROG", "A.ARTI")

PostgreSQL: sub-queries and aggregate functions(Sum)

I tried referring to other questions; I've inferred that sub-queries cannot be used on aggregate functions, but I cannot solve this use case.
Tables:
1. CustomerInfo(c_id,name)
2. ProductInfo(p_id,price)
3. ModelInfo(p_id,m_id,name)
4. PurchaseRecords(c_id,m_id,quantity)
Required output:
List of customer names, with total amount purchased by each customer.
My flow of thought is that:
Link PurchaseRecords with ModelInfo to get p_id,
ModelInfo with ProductInfo to get the price,
Multiply price returned by quantity in PurchaseRecords for every specific customer,
which requires me to link CustomerInfo in the end to get the name.
I'm using Postgres. I could write a program for that in Java, but I find it hard to do it with SQL. So, what is the correct query here? Any pointers on how to think problems out are appreciated!
SELECT
c.name as customer_name,
sum(coalesce(p.price, 0) * coalesce(pr.quantity, 0)) as amount_purchased
from
CustomerInfo c
left join PurchaseRecords pr on c.c_id = pr.c_id
left join ModelInfo mi on mi.m_id = pr.m_id
left join ProductInfo p on p.p_id = mi.p_id
group by
c.name

SQL displaying the right number, names

I'm working on a Coffee Shop database and trying to find number of sales per item. The number comes back correctly, but instead of displaying the name of the coffee and the sales it displays all the coffee names with the correct data of the first drink, then all of the coffee names with the correct data of the second drink.
select p.ProductName, TotalSold = SUM(o.Quantity)
From MSProducts p, MSOrderline o
Group By p.ProductName, o.ProductID
Output should be...
1 FlavoredSyrup-Shot 11
2 ExtraExpresso 7
3. Americano-Small 5
Though it didn't fit on the page it continues with the quantity 5 below.
I think the lack of join condition was the cause of data duplication. This may work, provided you have ProductID in both tables.
select p.ProductName, SUM(o.Quantity) as TotalSold
From MSProducts p
inner join MSOrderline o
on p.ProductID = o.ProductID
Group By p.ProductName
You need to map both the tables correctly.
MSProducts p, MSOrderline o
If you dont map then all the rows of first table will be mapped with all the rows of the second table. Please map it using the common column

SQL to XML transfer of data

Ok have been trying to learn SQL to XML the last few days and this is what I have been able to teach my self thus far.
`SELECT distinct StudentItem.foldername AS "foldername", StudentItem.status, StudentItem.vhrid, StudentItem.firstname, StudentItem.middleinitial, StudentItem.lastname,
dbo.getEnumDescript(StudentType, 'StudentType') AS title,
StudentItem.email,
dbo.getEnumDescript(OfficeLocation, 'OfficeLocation') AS Office,
practices.id as 'StudentItem/practices/practice/id',
practices.name as 'StudentItem/practices/practice/name',
schoolItem.Name as 'StudentItem/bio/schools/schoolItem/schoolname',
schoolItem.schoolYear as 'lawyerItem/bio/schools/schoolItem/schoolyear'
FROM [dbo].[Student] as lawyerItem
LEFT JOIN [dbo].[StudentGroups] as aprac on StudentItem.vhrid = aprac.vhrid
INNER JOIN [dbo].[PracticeGroups] as practices on aprac.PracticeGroupID = practices.ID
LEFT JOIN [dbo].[StudentEducation] as schoolItem on StudentItem.vhrid = schoolItem.vhrid
where StudentItem.vhrid='50330'
FOR XML path, ROOT ('StudentItem'), ELEMENTS;`
What I get is this
`<StudentItems>
<row>
<foldername>susan.wissink</foldername>
<status>1</status>
<vhrid>50330</vhrid>
<firstname>Susan</firstname>
<middleinitial>M.</middleinitial>
<lastname>Wissink</lastname>
<title>Student leader</title>
<email>swissink#blank.com</email>
<Office>Phoenix</Office>
<StudentItem>
<practices>
<practice>
<id>681</id>
<name>Real Estate Finance and Lending</name>
</practice>
</practices>
<bio>
<schools>
<schoolItem>
<schoolname><i>Best in America®</i>, ASU</schoolname>
<schoolyear>2016</schoolyear>
</schoolItem>
</schools>
</bio>
</StudentItem>
</row>
<row>
<foldername>susan.wissink</foldername>
<status>1</status>
<vhrid>50330</vhrid>
<firstname>Susan</firstname>
<middleinitial>M.</middleinitial>
<lastname>Wissink</lastname>
<title>Student leader</title>
<email>swissink#blank.com</email>
<Office>Phoenix</Office>
<StudentItem>
<practices>
<practice>
<id>681</id>
<name>Real Estate Finance and Lending</name>
</practice>
</practices>
<bio>
<schools>
<schoolItem>
<schoolname><i>Best in America®</i>, UOP</schoolname>
<schoolyear>2011-2015</schoolyear>
</schoolItem>
</schools>
</bio>
</StudentItem>
</row>`
But I'm trying to get the all the practices and schools to show up as one entry for the guy that. More or less I'm trying to get it to look like below.
`<StudentItems>
<row>
<foldername>susan.wissink</foldername>
<status>1</status>
<vhrid>50330</vhrid>
<firstname>Susan</firstname>
<middleinitial>M.</middleinitial>
<lastname>Wissink</lastname>
<title>Student leader</title>
<email>swissink#blank.com</email>
<Office>Phoenix</Office>
<StudentItem>
<practices>
<practice>
<id>681</id>
<name>Real Estate Finance and Lending</name>
<id>683</id>
<name>Business and Finance</name>
</practice>
</practices>
<bio>
<schools>
<schoolItem>
<schoolname><i>Best in America®</i>, UOP</schoolname>
<schoolyear>2011-2015</schoolyear>
<schoolname><i>Best in America®</i>, ASU</schoolname>
<schoolyear>2016</schoolyear>
</schoolItem>
</schools>
</bio>
</StudentItem>
</row>`
Any help would be welcome. Thank You.
Without sample data, it's difficult to write code and test for. But generally what you need to do is to create sub-queries to create your practice and schoolItem XML nodes. Something like this:
SELECT distinct StudentItem.foldername AS "foldername",
StudentItem.status,
StudentItem.vhrid,
StudentItem.firstname,
StudentItem.middleinitial,
StudentItem.lastname,
dbo.getEnumDescript(StudentType, 'StudentType') AS title,
StudentItem.email,
dbo.getEnumDescript(OfficeLocation, 'OfficeLocation') AS Office,
(
select practices.id, practices.name
from [dbo].[StudentGroups] as aprac
INNER JOIN [dbo].[PracticeGroups] as practices
on aprac.PracticeGroupID = practices.ID
where StudentItem.vhrid = aprac.vhrid
FOR XML path(''), type
) 'StudentItem/practices/practice',
(
select Name schoolname, schoolYear
from [dbo].[StudentEducation] schoolItem
where StudentItem.vhrid = schoolItem.vhrid
FOR XML path(''), type
) 'StudentItem/bio/schools/schoolItem'
FROM [dbo].[Student] as StudentItem
where StudentItem.vhrid='50330'
FOR XML path, ROOT ('StudentItem');

setting value from sql query to object

select pb.id,
p.name,
pb.batchName,
pb.batchCode,
s.detail,pb.program_id,
pb.session_id,
si.typeDescp,
si.id
from programBatch_info pb
join program p on pb.program_id=p.id
join session_info s on pb.session_id=s.id
join semester_info si on si.id=pb.semInfo_id
Here the name of first and last columns is 'id' so when I retrieve the values of this query first column object and last column object return the same value.But when I change the 'si.id' to 'pb.semInfo_id' the name of last column is'semInfo_id' and hence the correct values is retrieved. I tried this native query in hibernate platform.
Am I conceputally wrong or what is the actual case??
Not sure the question but try this:
select pb.id,
p.name,
pb.batchName,
pb.batchCode,
s.detail,pb.program_id,
pb.session_id,
si.typeDescp,
si.id as [si_id]
from programBatch_info pb
join program p on pb.program_id=p.id
join session_info s on pb.session_id=s.id
join semester_info si on si.id=pb.semInfo_id
This is the syntax to specify a new column name.