SPARQL same predicates with different values - sparql

I am using SPARQL to query my data from the triplestore.
In the triplestore I have a form containing a table, the table has different table entries. Each entry has a number of predicates. I want to use the predicates index and cost. My query needs to catch the first 2 rows, indices 0 and 1 and save the cost under a specific variable for each.
So I have tried the following (prefix ext is ommited) :
SELECT DISTINCT ?entry ?priceOne ?priceTwo
WHERE {
?form ext:table ?table.
?table ext:entry ?entry.
?entry ext:index 0;
ext:cost ?priceOne.
?entry ext:index 1;
ext:cost ?priceTwo.
}
This however does not show any values, if I remove the second part (with index 1) than I do get ?priceOne. How can I get both values?

Your current query finds each ?entry that has both ext:index values, 0 and 1. You could avoid this by using something like ?entry0 and ?entry1, essentially duplicating your triple patterns.
But typically, you would match alternatives with UNION:
SELECT DISTINCT ?entry ?priceOne ?priceTwo
WHERE {
# a shorter way to specify this, if you don’t need the ?table variable
?form ext:table/ext:entry ?entry .
{
?entry ext:index 0 ;
ext:cost ?priceOne .
}
UNION
{
?entry ext:index 1 ;
ext:cost ?priceTwo .
}
}

Related

AGE question: WITH clause doesn't work with MATCH/WITH

If I have the following query
select * from cypher('agload_test_graph', $$ match (n) with n where n.name='A' return n $$) as (sp agtype)
then n.name='A' doesn't work.
but if I remove with clause, then it works.
select * from cypher('agload_test_graph', $$ match (n) where n.name='A' return n $$) as (sp agtype)
I tried the example query in age document.
SELECT *
FROM cypher('graph_name', $$
MATCH (david {name: 'David'})-[]-(otherPerson)-[]->()
WITH otherPerson, count(*) AS foaf
WHERE foaf > 1RETURN otherPerson.name
RETURN otherPerson.name
$$) as (name agtype);
The problem with your first query is that the WHERE clause is not applied to the n variable because the WHERE clause is used before the WITH clause.  By WITHclause, a new variable that is a subset of the previous variable is created in Cypher. Any filters added after the the WITH clause will be applied to this new variable rather than the original variable. By deleting the WITH clause from your second query, the where clause is being applied directly to the n variable, which is what you want.
The example query in the age document you provided is a legitimate Cypher query. It uses MATCH to find a node with the name "David", then it uses  WITH clause to create a new variable otherPerson, which is the set of nodes nodes connected to the "David" node, and then uses  count(*) function to count the number of nodes connected to the "David" node. After this it uses the WHERE clause to filter otherPerson nodes where the count of their connections is greater than 1 and return their names.
The where clause after with is ignored. This is one of the issues in Apache Age which is opened on github. Issue Page

Filter != NULL in SPARQL

I have the following Query in GraphDB 9.4. As shown in the results includes "NULL"^^xsd:datetime. I use filter as shown in the comment to only select valid data. When I do so, I get no results (No data available in table). Even any other filter content will result in no results. Is there any other adjustment for the Filter necessary?
select Distinct ?PDID ?MAT ?PStart ?DT ?Duration where {
?PDID :DP1 ?PStart.
?PDID :OP1 ?PN.
?MAT :OP2 ?PN.
?MAT :DP2 ?DT.
# Filter (?PStart != "NULL")
# bind (ofn:hoursBetween(?PStart, ?DT) as ?Duration)
}
Results

Aggregate functions in Sparql query with empty records

I've been trying to run a sparql query against https://landregistry.data.gov.uk/app/qonsole# to yield some sold properties result.
The query is the following:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX ukhpi: <http://landregistry.data.gov.uk/def/ukhpi/>
SELECT sum(?ukhpi_salesVolume)
WHERE
{ { SELECT ?ukhpi_refMonth ?item
WHERE
{ ?item ukhpi:refRegion <http://landregistry.data.gov.uk/id/region/haringey> ;
ukhpi:refMonth ?ukhpi_refMonth
FILTER ( ?ukhpi_refMonth >= "2019-03"^^xsd:gYearMonth )
FILTER ( ?ukhpi_refMonth < "2020-03"^^xsd:gYearMonth )
}
}
OPTIONAL
{ ?item ukhpi:salesVolume ?ukhpi_salesVolume }
}
The problem is, the result from this is empty. However, if i run the same query without the SUM on the 4th line, i can see there are 11 integer records.
My thoughts are that there is a 12th, empty record which causes all the issues in the SUM operation, but sparql is not my storngest side so i'm not sure how to filter this (and remove any empty records) if that's really the problem.
I've also noticed that most of the aggregate functions do not work as well(min, max, avg). *Count does, and returns 11
I actually solved this myself, all that was needed was a coalesce which apparently existed in sparql too.
So:
SELECT sum(COALESCE(?ukhpi_salesVolume, 0))
instead of just
SELECT sum(?ukhpi_salesVolume)

SPARQL column headings with different name

I am new to SANSA-STACK and I am using SPARQL Query to perform some operations on Triples RDD , I am using Select with some column names, but when I am completing the query, the column names are getting changed to some random values.
val query = s""" PREFIX ns0: <https://www.example.com/discovery/catalog/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?ColumnRef
WHERE
{
{<https://www.example.com/db/h2/fred/2020/table/FRED.FRED.US_REGIONS}> ns0:column ?ColumnRef .}
}
"""
val result : sql.DataFrame = triples.sparql(query)
result.show()
The output of result.show() has the column name getting changed.
+--------------------+
| o|
+--------------------+
|https://www.examp...|
|https://www.examp...|
|https://www.examp...|
|https://www.examp...|
+--------------------+
I am new to this technology stack, please let me know what I am doing wrong.
Here is a temporary solution that works for my purposes that returns a dataframe with the expected column names. By decomposing rdd.sparql, the rewrite object can be used to obtain the column mappings: https://gist.github.com/JNKHunter/c16caa882993facb31a273ec274cb8e3
Warning: Sansa query often returns more than one column for each sparql selected element. In those cases this code simply concatenates those columns since columns after the first tend to contain empty strings. Concatenation may not be what you want, however I've yet to discover what those empty string dataframe columns represent.

num_rows in postgres always return 1

I'm trying to do a SELECT COUNT(*) with Postgres.
What I need: Catch the rows affected by the query. It's a school system. If the student is not registered, do something (if).
What I tried:
$query = pg_query("SELECT COUNT(*) FROM inscritossimulado
WHERE codigo_da_escola = '".$CodEscola."'
AND codigo_do_simulado = '".$simulado."'
AND codigo_do_aluno = '".$aluno."'");
if(pg_num_rows($query) == 0)
{
echo "Error you're not registered!";
}
else
{
echo "Hello!";
}
Note: The student in question IS NOT REGISTERED, but the result is always 1 and not 0.
For some reason, when I "show" the query, the result is: "Resource id #21". But, I look many times in the table, and the user is not there.
You are counting the number of rows in the answer, and your query always returns a single line.
Your query says: return one row giving the number of students matching my criteria. If no one matches, you will get back one row with the value 0. If you have 7 people matching, you will get back one row with the value 7.
If you change your query to select * from ... you will get the right answer from pg_num_rows().
Actually, don't count at all. You don't need the count. Just check for existence, which is proven if a single row qualifies:
$query = pg_query(
'SELECT 1
FROM inscritossimulado
WHERE codigo_da_escola = $$' . $CodEscola . '$$
AND codigo_do_simulado = $$' . $simulado. '$$
AND codigo_do_aluno = $$' . $aluno . '$$
LIMIT 1');
Returns 1 row if found, else no row.
Using dollar-quoting in the SQL code, so we can use the safer and faster single quotes in PHP (I presume).
The problem with the aggregate function count() (besides being more expensive) is that it always returns a row - with the value 0 if no rows qualify.
But this still stinks. Don't use string concatenation, which is an open invitation for SQL injection. Rather use prepared statements ... Check out PDO ...