SPARQL query gives different result as a subquery - subquery

When running the following query I get only one result as expected
SELECT DISTINCT ?city ?country WHERE {
FILTER (?city = wd:Q1748) .
# Primary country
?city p:P17 ?c .
?c ps:P17 ?country ;
wikibase:rank ?rank .
FILTER NOT EXISTS { ?c pq:P582 [] . } # Existing countries only
FILTER NOT EXISTS {
?city p:P17 [ wikibase:rank ?rank2 ] .
FILTER (?rank2 = wikibase:PreferredRank && ?rank != wikibase:PreferredRank) .
}
FILTER (?rank != wikibase:DeprecatedRank) .
}
However, I get two results if I query the same code as a subquery:
SELECT * WHERE {
{
SELECT DISTINCT ?city ?country WHERE {
FILTER (?city = wd:Q1748) .
# Primary country
?city p:P17 ?c .
?c ps:P17 ?country ;
wikibase:rank ?rank .
FILTER NOT EXISTS { ?c pq:P582 [] . } # Existing countries only
FILTER NOT EXISTS {
?city p:P17 [ wikibase:rank ?rank2 ] .
FILTER (?rank2 = wikibase:PreferredRank && ?rank != wikibase:PreferredRank) .
}
FILTER (?rank != wikibase:DeprecatedRank) .
}
}
}
According to the documentation the subquery is executed first and the result is then transferred to the outer query, so why does SELECT * not give the same result?

As explained in the Wikidata documentation here :
The “filter not exists” clause seems to often be inefficient for
unclear reasons. To work fine, queries with “filter not exists” often seem to have to be rewritten.
I modified your query and now both queries return the same results :
SELECT * WHERE {
{
SELECT DISTINCT ?city ?country WHERE {
FILTER (?city = wd:Q1748) .
# Primary country
?city p:P17 ?c .
?c ps:P17 ?country ;
wikibase:rank ?rank .
FILTER NOT EXISTS { ?c pq:P582 [] . } # Existing countries only
OPTIONAL {?city p:P17 [ wikibase:rank ?rank2 ] .}
FILTER (?rank2 = wikibase:PreferredRank && ?rank != wikibase:PreferredRank) .
FILTER (?rank != wikibase:DeprecatedRank) .
}
}
}
I also checked the ranks of p17 using the following query and wikibase:DeprecatedRank is not the results:
SELECT * WHERE {
wd:Q1748 p:P17 ?o. ?o ?p ?q.
}
wd:Q35 wikibase:PreferredRank
wd:Q756617 wikibase:NormalRank

Related

how to query many-to-many relation with Typeorm Query Builder using subquery

I'm new to typeorm. I have simple entities : Course and User. I have a third table table CourseUserMapper having course_id and user_id referencing to Course and User tables.
i've created subquery selecting user -> name, email, id
const totalInstructors = this.dataSource
.createQueryBuilder(User, 'u')
.select([
'u.name AS user_name',
'u.email AS user_email',
'cs.userId AS user_id',
'cs.courseId AS courseId',
])
.leftJoin(CourseInstructor, 'cs', 'cs.userId = u.id');
return await this.dataSource
.createQueryBuilder(Course, 'course')
.leftJoinAndMapMany(
'course.users',
'(' + totalInstructors.getQuery() + ')',
'instructors',
'instructors.courseId = course.id',
)
.where('course.id = :id', { id: course.id })
.getMany();
but the above query doesn't return users array list
Expected Result:
[
{
"id": 46,
"title": "course 1",
"description": "this is test course",
"users": [
{
"id": 9,
"name":"John Doe",
"email": "john#email.com"
},
{
"id": 10,
"name":"Anna",
"email":"anna#email.com"
}
]
}
]
Tried working with SQL, which seems to return user_name, user_email and user_id
SELECT
`course`.`id` AS `course_id`,
`course`.`title` AS `course_title`,
`course`.`description` AS `course_description`,
`instructors`.*
FROM `course` `course`
LEFT JOIN `chapter` `chapter`
ON `chapter`.`course_id` = `course`.`id`
LEFT JOIN (
SELECT
`u`.`name` AS user_name,
`u`.`email` AS user_email,
`cs`.`user_id` AS user_id,
`cs`.`course_id` AS course_id
FROM `users` `u`
LEFT JOIN `course_users` `cs`
ON `cs`.`user_id` = `u`.`id`
) `instructors`
ON instructors.course_id = `course`.`id`
WHERE ( `course`.`id` = 40 )
Can i know what i'm doing wrong with Typeorm.
Thanks in advance!!

check null values in terraform

I have a question on null values. The following is the tricky one for me. Can anyone suggest to me how can we check if the value is null?
locals {
application_vars = {
"oke_build" = [
"121",
"121",
"121",
]
"ipa" = [
"101.10.2,1",
"101.10.2,2",
null
]
"size" = [
"c4.8xlarge",
null,
null,
]
}
}
I want to verify if the list contains null values.
You can use compact function to return only non-null elements from a list.
Then, you could compare the length of the original list with the length of the list returned by the compact function.
locals {
application_vars = {
"oke_build" = [
"121",
"121",
"121",
]
"ipa" = [
"101.10.2,1",
"101.10.2,2",
null
]
"size" = [
"c4.8xlarge",
null,
null,
]
}
}
output "not_null_check_oke_build" {
value = length(compact(local.application_vars.oke_build)) == length(local.application_vars.oke_build) ? "has no null elements" : "has null elements"
}
output "not_null_check_ipa" {
value = length(compact(local.application_vars.ipa)) == length(local.application_vars.ipa) ? "has no null elements" : "has null elements"
}
output "not_null_check_size" {
value = length(compact(local.application_vars.size)) == length(local.application_vars.size) ? "has no null elements" : "has null elements"
}
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
not_null_check_ipa = "has null elements"
not_null_check_oke_build = "has no null elements"
not_null_check_size = "has null elements"
If you have too many lists to check, this would get repetitive & you gotta loop these with another for a loop. But for 2-3 lists, it's okay to have them this way.

Explode Array-Nested Array Spark SQL

I have a JSON structure with multiple nested arrays, like this:
{
"id": 10,
"packages": [
{
"packageId": 1010,
"clusters": [
{
"fieldClusterId": 101010,
"fieldDefinitions": [
{
"fieldId": 101011112999,
"fieldName": "EntityId"
}
]
}
]
}
]
}
I'm using spark sql to flatten the array to something like this:
id
packageId
fieldClusterId
fieldId
fieldName
10
1010
101010
101011112999
EntityId
The query ends up being a fairly ugly spark-sql cte with multiple steps:
%sql
with cte as(
select
id
explode(packages) as packages_exploded
from temp),
cte2 as (
select
id,
packages_exploded.packageId,
explode(packages_exploded.clusters) as col
from cte),
cte3 as (
select
id,
packageId,
col.fieldClusterId
explode(col.fieldDefinitions) as col
from cte2)
select
productId,
productName,
fieldClusterId,
fieldClusterName,
col.*
from cte3
Is there a nicer syntax to accomplish this multiple level explosion?
This is the way I would implement:
SELECT id,
packageId,
fieldClusterId,
inline(fieldDefinitions)
FROM
(SELECT id,
packageId,
inline(clusters)
FROM
(SELECT id,
inline(packages)
FROM TABLE_NAME))

How to "where" based on the last StructType of a list

Suppose I have a DataFrame of a StructType list column named 'arr', which can be described by the following json,
{
"otherAttribute": "blabla...",
"arr": [
{
"domain": "books",
"others": "blabla..."
}
{
"domain": "music",
"others": "blabla..."
}
]
}
{
"otherAttribute": "blabla...",
"arr": [
{
"domain": "music",
"others": "blabla..."
}
{
"domain": "furniture",
"others": "blabla..."
}
]
}
... ...
We want to filter out records such that the last StructType in "arr" has its "domain" attribute being "music". In the above example, we need to keep the firs record but discard the second record. Need help to write such "where" clause.
The answer is based on this data:
+---------------+----------------------------------------------+
|other_attribute|arr |
+---------------+----------------------------------------------+
|first |[[books, ...], [music, ...]] |
|second |[[books, ...], [music, ...], [furniture, ...]]|
|third |[[football, ...], [soccer, ...]] |
+---------------+----------------------------------------------+
arr here is an array of structs.
Each element of arr has attributes domain and others (filled with ... here).
DataFrame API approach (F is pyspark.sql.functions):
df.filter(
F.col("arr")[F.size(F.col("arr")) - 1]["domain"] == "music"
)
The SQL way:
SELECT
other_attribute,
arr
FROM df
WHERE arr[size(arr) - 1]['domain'] = 'music'
The output table will look like this:
+---------------+----------------------------+
|other_attribute|arr |
+---------------+----------------------------+
|first |[[books, ...], [music, ...]]|
+---------------+----------------------------+
Full code (suggesting using PySpark console):
import pyspark.sql.types as T
import pyspark.sql.functions as F
schema = T.StructType()\
.add("other_attribute", T.StringType())\
.add("arr", T.ArrayType(
T.StructType()
.add("domain", T.StringType())
.add("others", T.StringType())
)
)
df = spark.createDataFrame([
["first", [["books", "..."], ["music", "..."]]],
["second", [["books", "..."], ["music", "..."], ["furniture", "..."]]],
["third", [["football", "..."], ["soccer", "..."]]]
], schema)
filtered = df.filter(
F.col("arr")[F.size(F.col("arr")) - 1]["domain"] == "music"
)
filtered.show(100, False)
df.createOrReplaceTempView("df")
filtered_with_sql = spark.sql("""
SELECT
other_attribute,
arr
FROM df
WHERE arr[size(arr) - 1]['domain'] = 'music'
""")
filtered_with_sql.show(100, False)

N1ql to Get data from collection based on field value

I have a document as below
{
"GMParcelStatus": {
"storeNumber": 5678,
"GMVehicleTrips": {
"GMVehicleTrip": [
{
"GMVehicleTripId": "1000101",
"MultiChannelOrders": {
"MultiChannelOrder": [
{
"multiChannelOrderID": "4BQGBNJ3U",
"multichannelParcels": [
{
"multiChannelParcelStatus": "LOADING_MISSING",
"UPI": "00000008101058629797"
},
{
"multiChannelParcelStatus": "OUTFORDELIVERY",
"UPI": "00000008101058684938"
}
]
},
{
"multiChannelOrderID": "4BQGUNY56W",
"multichannelParcels": [
{
"multiChannelParcelStatus": "DELIVERED",
"UPI": "00000008101058629793"
},
{
"multiChannelParcelStatus": "DELIVERED",
"UPI": "00000008101058684932"
}
]
}
]
}
}
]
}
},
"_class": "com.tesco.bean.MultiChannelParcelRequestVO"
}
I want to get all the document in my bucket data based on storeNumber and GMVehicleTripId.
I have 4 document similar to above with different GMVehicleTripId.
I have written N1ql query like below Select d.* from Delivery d JOIN Delivery.GMParcelStatus.GMVehicleTrips.GMVehicleTrip[0] b
on keys meta(d).id where b.GMVehicleTripId in ['1000101']
but i don't want to do this GMVehicleTrip[0].
please get me the right way to do.
Thanks,
Vinay J
SELECT d.* FROM Delivery d JOIN Delivery b ON KEYS meta(d).id
WHERE ANY v IN b.GMParcelStatus.GMVehicleTrips.GMVehicleTrip SATISFIES v.GMVehicleTripId IN ['1000101'] END;

Resources