Oussama L.
Oussama L.

Reputation: 1912

SPARQL combine - concatenate two columns into one

I'm a newbie to SPARQL, and I would like to combine two columns into one

initial table

a|b|1
c|d|2

wanted table

a|b
c|d
b|1
d|2

its like creating two different tables and putting them one on the other.

I need that to make a visualisation using d3sparql which takes this data form, I also though about importing a json and modifying it then printing it to the screen, but if this is possible that makes things a lot easier and faster..


UPDATE: My original Query looks like that

PREFIX prefix1:<...>
PREFIX prefix2:<...>
SELECT ?x ?y ?z 
WHERE  { 
?x prefix1:OwnsY ?y.
?y prefix1:PublishesZ ?z.
}

Upvotes: 1

Views: 1503

Answers (2)

Joshua Taylor
Joshua Taylor

Reputation: 85823

If you're just trying to extract all the subjects and objects of the owns and published triples, then this can be a very simple query. If, on the other hand, you only want data where there's all three parts, you'll need a full union. Let's create some example data and see what we can do:

@prefix : <urn:ex:>

:a :owns :b .
:b :publishes 1 .

:c :owns :d .
:d :publishes 2 .

:e :owns :f .  # no corresponding :publishes

:g :publishes :h .  # no corresponding :ownsprefix : <urn:ex:>

Here's your current query and results:

select ?x ?y ?z {
  ?x :owns ?y .
  ?y :publishes ?z .
}

---------------
| x  | y  | z |
===============
| :a | :b | 1 |
| :c | :d | 2 |
---------------

Now, if you're willing to get those owns and publishes triples that don't have corresponding publishes and owns triples, you can use a union, values block, or property path. The union would be

{ ?x :owns ?y } union { ?x :publishes ?y }

The values block would would be a bit simpler:

values ?p { :owns :publishes }
?x ?p ?y

You can make that even simpler with a property path:

?x :owns|:publishes ?y

These all give you:

-----------
| x  | y  |
===========
| :a | :b |
| :b | 1  |
| :c | :d |
| :d | 2  |
| :e | :f | * owns
| :g | :h | * publishes
-----------

Note that the rows with stars are present because "e owns f" and "g publishes h", even though there's nothing that f publishes, and nothing that owns g. Your original query won't find those. If you need to exclude the owns and publishes triples that don't have publishes and own counterparts, you'll need to use the union option, that includes all the parts as in user205512's answer.

Upvotes: 1

user205512
user205512

Reputation: 8888

The simplest way (but not the most efficient) is:

PREFIX prefix1:<...>
PREFIX prefix2:<...>
SELECT DISTINCT ?x ?z 
WHERE  {
    { ?x prefix1:OwnsY ?y. ?y prefix1:PublishesZ ?z. }
    UNION
    { ?x prefix1:OwnsY ?z. ?z prefix1:PublishesZ ?whatever. }
}

which in effect performs the query twice.

Upvotes: 2

Related Questions