1

I have a number of integer values in the object part of the RDF triples like following:

subject predicate object
  :a1    :d1       2017
  :a2    :d1     201601
  :a3    :d1     20170510

I need to find whether subject :a1's object value is greater than :a2's object value and :a2's object value is greater than :a3's object value or not through SPARQL. However, before writing that query, I need to make all the object values eight digits by adding extra zeros to the right side of the value like following:

subject predicate  object
  :a1    :d1      20170000
  :a2    :d1      20160100
  :a3    :d1      20170510

Could please let me know how to format object values to eight digits integer in SPARQL? Thank you.

TallTed
  • 9,069
  • 2
  • 22
  • 37
Beautiful Mind
  • 5,828
  • 4
  • 23
  • 42
  • Hacky combination of functions regarding string length and string concatenation should work. – UninformedUser Dec 06 '17 at 18:46
  • I need integer as an output not string. – Beautiful Mind Dec 06 '17 at 18:47
  • I understand this, but you need the number of digits `n` which can be done by using the length of the string of the literal. Afterwards, you can either multiply by `10^n` or append `n` times 0. – UninformedUser Dec 06 '17 at 18:56
  • And by the way, you can create an integer from a string using the XPath constructor. – UninformedUser Dec 06 '17 at 18:56
  • Could you please provide me an example code? Thanks a lot for your help. – Beautiful Mind Dec 06 '17 at 18:58
  • I'm still not sure, some math operations might be missing. Why don't you do comparison on the lexical form of the integer value? `order by desc(str(?value))` will order it correctly – UninformedUser Dec 06 '17 at 19:12
  • And possibly [`afn:sprintf`](https://jena.apache.org/documentation/query/library-function.html). – Stanislav Kralin Dec 06 '17 at 19:13
  • If you're using Jena, starting from `BIND(STRLEN(STR(?value)) as ?numDigits)` and then using some built-in math functions will work. – UninformedUser Dec 06 '17 at 19:14
  • Here we go: `prefix : prefix math: select * { ?s :d ?v . BIND(STRLEN(STR(?v)) as ?n) BIND((?v * math:pow(10, 8 - ?n)) AS ?vext ) } order by desc(str(?v))` – UninformedUser Dec 06 '17 at 19:18
  • Thank you. I am using Virtuoso triplestore. It is giving me following error:`Virtuoso 42001 Error SR185: Undefined procedure DB.DBA.http://www.w3.org/2005/xpath-functions/math#pow.` – Beautiful Mind Dec 06 '17 at 19:50
  • Instead of your second BIND I have added following code: `BIND (IF(?n=6, ?v*100, IF(?n=4, ?v*10000, ?v) ) AS ?vext)`. It works for most of the integer values. However, for some eight digit values, it adds extra zeros like following: 2016040100. Do you know why it is? – Beautiful Mind Dec 06 '17 at 21:54
  • These look very much like date strings. I wonder why you're not comparing them so? Also, you say your data is in Virtuoso, but your question is tagged with sparqlwrapper and jena. Which of these are correct? More accuracy on your part will greatly improve the chances you get useful answers. – TallTed Dec 07 '17 at 00:50
  • Also, it's often helpful to provide your *actual* goal, as well as what *you* think the best path there is, and *why* ... as well as what you've tried, and how well (or badly) it worked. – TallTed Dec 07 '17 at 01:34
  • @S.M.ShamimulHasan, you could also try [this query](https://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&qtxt=SELECT+*+WHERE+%7B%0D%0AVALUES+%28%3Fs%29+%7B%28%221234%22%5E%5Exsd%3Astring%29+%28%22123456%22%5E%5Exsd%3Astring%29+%28%2212345678%22%5E%5Exsd%3Astring%29%7D%0D%0ABIND+%28xsd%3Ainteger%28CONCAT%28%3Fs%2C+bif%3Arepeat%28%220%22%2C+8+-+bif%3Alength%28%3Fs%29%29%29%29+AS+%3Fs8%29%0D%0A%7D%0D%0A&format=text%2Fhtml). – Stanislav Kralin Dec 07 '17 at 12:40
  • 3
    If the number is too short, append "0000000" and then truncate to the right length. Beware of numbers too long. – AndyS Dec 07 '17 at 14:26

1 Answers1

2

You can use the following, i don't know if there is a PAD function in SPARQL

SELECT xsd:integer(substr(concat(str(?o),"00000000"),1,8))