<?xml version="1.0" encoding="UTF-8"?>
<Data>
<A><DelInfo>123-20150308-345</DelInfo><OrderNo>11</OrderNo></A>
<A><DelInfo>1204-20150308-355</DelInfo><OrderNo>15</OrderNo></A>
<A><DelInfo>153-20150408-343</DelInfo><OrderNo>10</OrderNo></A>
<A><DelInfo>44345-20150308-341</DelInfo><OrderNo>21</OrderNo></A>
<A><DelInfo>153-20150204-245</DelInfo><OrderNo>1</OrderNo></A>
<A><DelInfo>423-20150311-445</DelInfo><OrderNo>13</OrderNo></A>
..........
</Data>
I receive following XML. The DelInfo node contains a combination of
EmpId, Delivery Date and Receipt No. The OrderNo node contains the
order number wrt the Delivery Information.
The XML is stored in BaseX and I need following report to be generated from the
above XML.
<A><DelInfo>123-20150308-345</DelInfo><OrderNo>11</OrderNo><Report>20150308 - 11</Report></A>
.....
In other word, I want to insert an additional node Report with Date and Order No.
Any idea?
Replace yourdoc with your document name.
for $x in doc('yourdoc')//A
let $d := substring-before(substring-after($x/DelInfo, "-"), "-")
let $o := $x/OrderNo/text()
let $i := <C>{concat($d, " - ", $o)}</C>
return
insert node $i after $x/OrderNo
The inner substring-after() will return the string after the first -. Then, the substring-before() will return the string before the -. This way you will get the Date portion.
Related
I have a master table containing URLs:
CREATE TABLE IF NOT EXISTS MasterTable (url, masterId, PRIMARY KEY(url), UNIQUE(masterId));
An url string looks like this: file:///Users/user1/Pictures/rubus_and_apple.jpeg.
Now I want to lookup on the url column but only on the filename rubus_and_apple and not on all url string. (Meaning only on the last component of the url w/o extension).
For example I want to look the keyword rubus and get the url:file:///Users/user1/Pictures/rubus_and_apple.jpeg.
I need my query to be like:
SELECT masterId
FROM MasterTable
WHERE <url last component w/o extension> LIKE '%/rubus%';
How can I do so?
You could use LIKE:
SELECT masterId
FROM MasterTable
WHERE url LIKE '%/rubus.%';
Please note that this expression is not-SARGable so it won't use index.
EDIT:
WITH MasterTable(MasterId, url) AS(
VALUES(1, 'file:///Users/user1/Pictures/rubus_and_apple.jpeg')
)
SELECT *
FROM MasterTable
WHERE REPLACE(url,RTRIM(url,REPLACE(url,'/','')),'') LIKE '%' || 'rubus' || '%';
-- part of string after last /
db<>fiddle demo
There are lots of audit documents in my database like below
<Record>
<objectType>Audit</objectType>
<dateCreated>2017-04-07T03:51:56.231-04:00</dateCreated>
<createdBy>first user</createdBy>
</Record>
How can I get total number of user(createdBy) who created audit file in last 30 days? There are some audit files in which createdBy same so we require distinct value count.
I tried the query below:
let $query := cts:values(cts:element-reference(fn:QName($NS, "createdBy")))
return fn:count($query)
But how can I use condition dateCreated>30 or cts:range-query inside cts:values.
Is there any other way to achieve this?
(I have set up element range index for createdBy and dateCreated)
You can pass the constraining range query as the third argument to cts:count-aggregate() - something along the following lines should work:
let $index := fn:QName($NS, "dateCreated")
let $count := cts:count-aggregate(
cts:element-reference($index),
(),
cts:element-range-query($index, ">",
fn:current-dateTime() - xs:dayTimeDuration("P30D")
)
)
That should give you the total number of dateCreated values for the past 30 days.
For more information, see:
http://docs.marklogic.com/cts:count-aggregate
I am using a XQuery to query database in an OSB project. Consider the
following table:
userId Name Category
------ ------- --------
1 Dheepan Student
2 Raju Student
and the XQuery
let $userName:=fn-bea:execute-sql(
$dataSourceJndiName,
xs:string("NAME"),
xs:string("select NAME from USER where CATEGORY= 'Student'")
)/*:NAME[1]
return <root> {data($userName)} </root>
For this query I am getting the result as <root>Dheepan Raju</root>. But I
need to return only one row even the query returns more than one row like the
following <root>Dheepan</root>. I have used predicate [1] in the query but
no clue why it concatenates the values and returning. Can anybody tell me how
to return only the first row when more than one row is returned.
You need to use proper paranthesis:
let $userName:=(fn-bea:execute-sql(
$dataSourceJndiName,
xs:string("NAME"),
xs:string("select NAME from USER where CATEGORY= 'Student'")
)/*:NAME)[1]
return <root> {data($userName)} </root>
I've created a table
Movie ( title varchar2(40), review XMLTYPE)
And review has: `
<review>
<reviewer>...</reviewer>
<title> ....</title>
<rating>.....</rating> </Review> </reviewer>
When I try to access :
SELECT X.reviewername FROM movie m, XMLTABLE ('for $d in /reviews/review
return $d'
PASSING OBJECT_VALUE
columns
reviewername VARCHAR2(50) PATH 'reviewer') AS X
I get an error at OBJECT_VALUE. Where am I going wrong?
EDIT: I changed the Query to
SELECT m.title,
warehouse2.*
FROM movie M,
XMLTABLE('/REVIEW'
PASSING m.reviews
COLUMNS
"Rail" varchar2(60) PATH '//RATING')
warehouse2;
But no rows are getting selected. Any suggestions?
Well for one thing, don't you have a typo: '/reviews/review ' ? there is no element called anywhere in your example.
Your XML isn't well formed, you have overlapping tags, you have mismatched reviews/Reviews (XML is case sensitive) and in your query you have reviews/review but your xml has /review (no s on the end). –
I have XML db with only one collection (container) and I don't know the document names. How to get a entire XML document from db, which complies WHERE clause?
<root>
<node1>
<node2>
<node3>My Content</node2>
</node2>
</node1>
<root>
When I have queries
query 'collection("data1.dbxml")/root/node1/node2[node3 = "My Content"]/string()'
it returns a content from that node3
'My Content'
and
query 'collection("data1.dbxml")/root/ode1/node2/node3'
it returns 2 internal nodes with the content
<node2><node3>My Content</node3></node2>
But how to get whole document which complies this WHERE clause (sth like SELECT * FROM data2.dbxml WHERE node3='My Content'?
Simply use a predicate as you did in the first example:
collection("data1.dbxml")/root[node1/node2/node3 = "My Content"]
You can think of the predicate in XQuery as the WHERE in SQL and the SELECT-part is everything before.
another resolution ... after studying :)
query 'for $x in collection("data1.dbxml")
where $x/root/node1/node2/node3 = "My Content"
return $x'
or when we know the depth of node in XMLdoc and node's name
query 'for $x in collection("data1.dbxml")
where $x/*/*/*/node3 = "My Content"
return $x'
thanks W3Schools