cypher query with subpath and exists in redisgraph - cypher

I'm evaluating RedisGraph and I'm trying to replicate a result I have in Neo4j.
Graph and query are from my other question, I'm trying to achieve the same result: the path f1 <- (friend) m2 <- (sibling) b3 <- (coworker) d4 (and none of the p* nodes)
Nodes:
CREATE (a:temporary {name: 'm2'});
CREATE (a:temporary {name: 'f1'});
CREATE (a:temporary {name: 'b3'});
CREATE (a:temporary {name: 'd4'});
CREATE (a:temporary {name: 'p5'});
CREATE (a:temporary {name: 'p6'});
CREATE (a:temporary {name: 'p7'});
CREATE (a:temporary {name: 'k1'});
CREATE (a:temporary {name: 'k2'});
and relations:
MATCH (a) WHERE a.name = 'b3' MATCH (b) where b.name = 'm2' CREATE (a)-[:KNOWS {type: 'sibling'}]->(b);
MATCH (a) WHERE a.name = 'm2' MATCH (b) where b.name = 'f1' CREATE (a)-[:KNOWS {type: 'friend'}]->(b);
MATCH (a) WHERE a.name = 'd4' MATCH (b) where b.name = 'b3' CREATE (a)-[:KNOWS {type: 'coworker'}]->(b);
MATCH (a) WHERE a.name = 'p7' MATCH (b) where b.name = 'p6' CREATE (a)-[:KNOWS {type: 'friend'}]->(b);
MATCH (a) WHERE a.name = 'p6' MATCH (b) where b.name = 'p5' CREATE (a)-[:KNOWS {type: 'coworker'}]->(b);
MATCH (a) WHERE a.name = 'k1' MATCH (b) where b.name = 'b3' CREATE (a)-[:HAS]->(b);
MATCH (a) WHERE a.name = 'k1' MATCH (b) where b.name = 'd4' CREATE (a)-[:HAS]->(b);
MATCH (a) WHERE a.name = 'k1' MATCH (b) where b.name = 'm2' CREATE (a)-[:HAS]->(b);
MATCH (a) WHERE a.name = 'k1' MATCH (b) where b.name = 'f1' CREATE (a)-[:HAS]->(b);
MATCH (a) WHERE a.name = 'k2' MATCH (b) where b.name = 'p5' CREATE (a)-[:HAS]->(b);
MATCH (a) WHERE a.name = 'k2' MATCH (b) where b.name = 'p7' CREATE (a)-[:HAS]->(b);
MATCH (a) WHERE a.name = 'k2' MATCH (b) where b.name = 'p6' CREATE (a)-[:HAS]->(b);
The original Cypher query:
match p=(a:temporary)-[:KNOWS*0..]->(b)
where not ()-[:KNOWS]->(a) and not (b)-[:KNOWS]->()
and exists { match (k)-[:HAS]->(a) where k.name='k1' }
return p
Gives the following error, about the subpath in the EXISTS:
Invalid input '(': expected ':', ',' or '}' line: 1, column: 112, offset: 111 errCtx: ... (b)-[:KNOWS]->() and exists { match (k)-[:HAS]->(a) where k.name='k1' } r... errCtxOffset: 40
I've rewritten it like this (with an additional MATCH clause: is this equivalent to the above?
GRAPH.QUERY test "match p=(a:temporary)-[:KNOWS*0..]->(b) where not ()-[:KNOWS]->(a) and not (b)-[:KNOWS]->() with a, p match (k)-[:HAS]->(a) where k.name='k1' return p"

It's equivalent, rewrite:
MATCH (k)-[:HAS]->(a:temporary) WHERE k.name='k1'
MATCH p = (a)-[:KNOWS*0..]->(b)
WHERE not ()-[:KNOWS]->(a) AND not (b)-[:KNOWS]->()
RETURN p

Related

Create subquery using peewee, using `.select` on the subquery results

I have a rather complex peewee query that looks like that:
SolutionAlias = Solution.alias()
fields = [
SolutionAlias.id.alias('solution_id'),
SolutionAlias.solver.id.alias('solver_id'),
SolutionAlias.exercise.id.alias('exercise_id'),
]
query = (
User
.select(*fields)
.join(Exercise, JOIN.CROSS)
.join(Course, JOIN.LEFT_OUTER, on=(Exercise.course == Course.id))
.join(SolutionAlias, JOIN.LEFT_OUTER, on=(
(SolutionAlias.exercise == Exercise.id)
& (SolutionAlias.solver == User.id)
))
.where(
(Exercise.id << self.get_exercise_ids()),
(User.id << self.get_user_ids()),
)
.group_by(Exercise.id, User.id, SolutionAlias.id)
.having(
(SolutionAlias.id == fn.MAX(SolutionAlias.id))
| (SolutionAlias.id.is_null(True))
)
.alias('solutions_subquery')
)
full_query_fields = [
query.c.solver_id,
query.c.exercise_id,
Solution.id.alias('solution_id'),
SolutionAssessment.icon.alias('assessment_icon'),
]
solutions = (
Solution
.select(*full_query_fields)
.join(query, JOIN.RIGHT_OUTER, on=(
Solution.id == query.c.solution_id
))
.join(SolutionAssessment, JOIN.LEFT_OUTER, on=(
(Solution.assessment == SolutionAssessment.id)
))
)
This one actually works, generating the following SQL query:
SELECT
"solutions_subquery"."solver_id",
"solutions_subquery"."exercise_id",
"t1"."id" AS "solution_id",
"t2"."icon" AS "assessment_icon"
FROM
"solution" AS "t1"
RIGHT OUTER JOIN (
SELECT
"t3"."id" AS "solution_id",
"t4"."id" AS "solver_id",
"t5"."id" AS "exercise_id"
FROM
"user" AS "t4" CROSS
JOIN "exercise" AS "t5"
LEFT OUTER JOIN "course" AS "t6" ON ("t5"."course_id" = "t6"."id")
LEFT OUTER JOIN "solution" AS "t3" ON (
("t3"."exercise_id" = "t5"."id")
AND ("t3"."solver_id" = "t4"."id")
)
WHERE
(
(
"t5"."id" IN (155, 156, 157)
)
AND (
"t4"."id" IN (1, 24, 25, 26, 27, 28)
)
)
GROUP BY
"t5"."id",
"t4"."id",
"t3"."id"
HAVING
(
(
"t3"."id" = MAX("t3"."id")
)
OR ("t3"."id" IS NULL)
)
) AS "solutions_subquery" ON (
"t1"."id" = "solutions_subquery"."solution_id"
)
LEFT OUTER JOIN "solutionassessment" AS "t2" ON ("t1"."assessment_id" = "t2"."id")
But I don't really want to use RIGHT_JOIN as it isn't supported by SQLite.
When trying to query using the subquery query and JOINing the Solution table into the subquery's result, I get an error from peewee.
The new query:
solutions = (
query
.select(*full_query_fields)
.join(Solution, JOIN.LEFT_OUTER, on=(
Solution.id == query.c.solution_id
))
.join(SolutionAssessment, JOIN.LEFT_OUTER, on=(
(Solution.assessment == SolutionAssessment.id)
))
)
The generated query:
SELECT
"solutions_subquery"."solver_id",
"solutions_subquery"."exercise_id",
"t1"."id" AS "solution_id",
"t1"."checker_id",
"t1"."state",
"t1"."submission_timestamp",
"t2"."name" AS "assessment",
"t2"."icon" AS "assessment_icon"
FROM
"user" AS "t3" CROSS
JOIN "exercise" AS "t4"
LEFT OUTER JOIN "course" AS "t5" ON ("t4"."course_id" = "t5"."id")
LEFT OUTER JOIN "solution" AS "t6" ON (
("t6"."exercise_id" = "t4"."id")
AND ("t6"."solver_id" = "t3"."id")
)
LEFT OUTER JOIN "solution" AS "t1" ON (
"t1"."id" = "solutions_subquery"."solution_id"
)
LEFT OUTER JOIN "solutionassessment" AS "t2" ON ("t1"."assessment_id" = "t2"."id")
WHERE
(
(
"t4"."id" IN (155, 156, 157)
)
AND (
"t3"."id" IN (1, 24, 25, 26, 27, 28)
)
)
GROUP BY
"t4"."id",
"t3"."id",
"t6"."id"
HAVING
(
(
"t6"."id" = MAX("t6"."id")
)
OR ("t6"."id" IS NULL)
)
Which results in:
psycopg2.errors.UndefinedTable: missing FROM-clause entry for table "solutions_subquery"
LINE 1: ...EFT OUTER JOIN "solution" AS "t1" ON ("t1"."id" = "solutions...
During handling of the above exception, another exception occurred:
[Truncated for readability...]
loguru.logger.critical(str(list(solutions.dicts().execute())))
[Truncated for readability...]
peewee.ProgrammingError: missing FROM-clause entry for table "solutions_subquery"
LINE 1: ...EFT OUTER JOIN "solution" AS "t1" ON ("t1"."id" = "solutions...
Why does peewee flatten the query? Is there another way to use LEFT_JOIN?
Eventually found the Select function in the documentation, which allows me to kind of wrap the previous query:
solutions = (
Select(columns=full_query_fields)
.from_(query)
.join(Solution, JOIN.LEFT_OUTER, on=(
Solution.id == query.c.solution_id
))
.join(SolutionAssessment, JOIN.LEFT_OUTER, on=(
(Solution.assessment == SolutionAssessment.id)
))
)
This solution works.

How to use intersect operator in MongoDB?

(select A from 'TableB' where C = c and G = g)
intersect
(select A from 'TableB' where C = d and G = h)
First of all, because Mysql does not provide an intersect operator, I changed the query statement written above as follows.
select A
from 'TableB'
where C = c and G = g and A in(
select A
from 'TableB'
where C = d and G = h)
I want to use MongoDB to get the same result as above.
Is there any other way??
let mongoQuery = {
$and:[
{C: c},
{D: d},
{G: g},
{G: h}
]
};
const result = await TableB.find(mongoQuery, {A: 1});
This query will return only elements from 'A' that matches C=c, D=d, G=h, G=g
Hope it helps

In Karate how can we verify if the query with where condition has two results?

I have a scenario where the SQL query with a where condition will result in 2 Rows. How can assert if it is resulting in 2 rows? At present, the karate is throwing an error org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 2
* def response = db.readRow( 'SELECT * from database_name.table_name where id = \"'+ id + '\";')
I believe this should help you : https://github.com/intuit/karate#schema-validation
* def foo = ['bar', 'baz']
# should be an array of size 2
* match foo == '#[2]'
Also, you should use db.readRows instead of db.readRow.
* def dogs = db.readRows('SELECT * FROM DOGS')
* match dogs contains { ID: '#(id)', NAME: 'Scooby' }
* def dog = db.readRow('SELECT * FROM DOGS D WHERE D.ID = ' + id)
* match dog.NAME == 'Scooby'

python- how to join two seperate queries based on common value

I have two queries which links to different databases
query = "select name ,ctry from xxxx where xxxx"
cursor.execute(query)
results1 = list(cursor.fetchall())
for row in results1:
query1 = "SELECT sessionname, country FROM xxx where and sessions.sessionname = '"+row[0] +"'"
cur.execute(query1)
results2.append(cur.fetchall())
How to connect them if they have common value(sessionname and name) and save it's output to file. Both queries are located in different dbo (oracle, postgresql)
My code is here :
try:
query = """select smat.s_name "SQLITE name" ,smed.m_ctry as "Country", smed.m_name "HDD Label" from smart.smed2smat ss, smart.smed smed, smart.smat smat where ss.M2S_SMAT=smat.s_id and ss.m2s_smed=smed.m_id and smed.m_name like '{0}%' order by smat.s_name""" .format(line_name)
cursor.execute(query)
columns = [i[0] for i in cursor.description]
results1 = cursor.fetchall()
for row in results1:
query1 = "SELECT sessions.sessionname, projects.country , projects.projectname FROM momatracks.sessions, momatracks.projects, momatracks.sessionsgeo where sessions.projectid = projects.id and sessionsgeo.sessionname = sessions.sessionname and sessions.sessionname = '"+row[0] +"' order by sessions.sessionname"
cur.execute(query1)
results2 =cur.fetchall()
print "results1 -----> \n:", row
tmp=[]
output_items = []
for tmp in results2:
print "---> \n", tmp
try:
stations_dict = dict([(item[0], item[1:]) for item in tmp])
for item in row:
output_item = list(item) + stations_dict.get(item[0], [])
output_items.append(output_item)
except Exception, f:
print str (f)
cursor.close()
cur.close()
except Exception, g:
print str ( g )
except Exception, e:
print str ( e )
My results from row and tmp are :
row - WE246JP_2015_10_11__14_53_33', 'NLD', '031_025_SQLITE_NLD1510_03INDIA
and
tmp - WE246JP_2015_10_11__14_53_33', 'NLD', 'NLD15_N2C1-4_NL'
How to properly connect them? I want output look like this :
output_items - WE246JP_2015_10_11__14_53_33', 'NLD', '031_025_SQLITE_NLD1510_03INDIA', 'NLD15_N2C1-4_NL'
At the moment i get this error :
can only concatenate list (not "str") to list
Also value station_dict looks like this :( And this is not what i intended to do
'W': 'E246JP_2015_10_11__15_23_33', 'N': 'LD15_N2C1-4_NL3'
I know there is something wrong with my code which is simmilar to join. Can anyone explain this to me ? I used method below :
http://forums.devshed.com/python-programming-11/join-arrays-based-common-value-sql-left-join-943177.html
If the sessions are exactly the same in both databases then just zip the results:
query = """
select
smat.s_name "SQLITE name",
smed.m_ctry as "Country",
smed.m_name "HDD Label"
from
smart.smed2smat ss
inner join
smart.smed smed on ss.M2S_SMAT = smat.s_id
inner join
smart.smat smat on ss.m2s_smed = smed.m_id
where smed.m_name like '{0}%'
order by smat.s_name
""".format(line_name)
cursor.execute(query)
results1 = cursor.fetchall()
query1 = """
select
sessions.sessionname,
projects.country,
projects.projectname
from
momatracks.sessions,
inner join
momatracks.projects on sessions.projectid = projects.id
inner join
momatracks.sessionsgeo on sessionsgeo.sessionname = sessions.sessionname
where sessions.sessionname in {}
order by sessions.sessionname
""".format(tuple([row[0] for row in results1]))
cur.execute(query1)
results2 = cur.fetchall()
zipped = zip(results1, results2)
output_list = [(m[0][0], m[0][1], m[0][2], m[1][2]) for m in zipped]
If the sessions are different then make each result a dictionary to join.
I think you can use a subquery here. There's no way for me to test it, but I think it should look like this:
SELECT *
FROM (SELECT smat.s_name "SQLITE name" ,
smed.m_ctry as "Country",
smed.m_name "HDD Label"
FROM smart.smed2smat ss,
smart.smed smed,
smart.smat smat
WHERE ss.M2S_SMAT=smat.s_id
AND ss.m2s_smed=smed.m_id
AND smed.m_name like '{0}%'
ORDER BY smat.s_name) t1,
(SELECT sessions.sessionname,
projects.country ,
projects.projectname
FROM momatracks.sessions,
momatracks.projects,
momatracks.sessionsgeo
WHERE sessions.projectid = projects.id
AND sessionsgeo.sessionname = sessions.sessionname
AND sessions.sessionname = '"+row[0] +"'
ORDER BY sessions.sessionname) t2
WHERE t1."SQLITE name" = t2.sessionname ;

How to join three tables?

SELECT
PC_SL_ACNO, -- DB ITEM
SLNAME, -- ACCOUNT NAME:
SL_TOTAL_AMOUNT -- TOTAL AMOUNT:
FROM GLAS_PDC_CHEQUES
WHERE PC_COMP_CODE=:parameter.COMP_CODE
AND pc_bank_from = :block02.pb_bank_code
AND pc_due_date between :block01.date_from
AND :block01.date_to
AND nvl(pc_discd,'X') IN(‘X’, 'R')
GROUP BY
pc_comp_code, pc_sl_ldgr_code, pc_sl_acno
ORDER BY pc_sl_acno
ACCOUNT NAME:
BEGIN
SELECT COAD_PTY_FULL_NAME INTO :BLOCK03.SLNAME
FROM GLAS_PTY_ADDRESS,GLAS_SBLGR_MASTERS
WHERE SLMA_COMP_CODE = :PARAMETER.COMP_CODE
AND SLMA_ADDR_ID = COAD_ADDR_ID
AND SLMA_ADDR_TYPE = COAD_ADDR_TYPE
AND SLMA_ACNO = :BLOCK03.PC_SL_ACNO
AND SLMA_COMP_CODE = COAD_COMP_CODE;
EXCEPTION WHEN OTHERS THEN NULL;
END;
TOTAL AMOUNT:
BEGIN
SELECT SUM(PC_AMOUNT) INTO :SL_TOTAL_AMOUNT
FROM GLAS_PDC_CHEQUES
WHERE PC_DUE_DATE BETWEEN :BLOCK01.DATE_FROM AND :BLOCK01.DATE_TO
AND PC_BANK_FROM = :block02.PB_BANK_CODE
AND PC_SL_ACNO = :BLOCK03.PC_SL_ACNO
AND NVL(PC_DISCD,'X') = 'R'
AND PC_COMP_CODE = :PARAMETER.COMP_CODE;
EXCEPTION WHEN OTHERS THEN :block03.SL_TOTAL_AMOUNT := 0;
END;
How can I join the three tables?
You'll have to adjust depending on precisely what criteria and required fields you have for your query or queries.
SELECT
c.PC_SL_ACNO,
a.COAD_PTY_FULL_NAME,
SUM(c.PC_AMOUNT)
FROM
GLAS_PDC_CHEQUES c
LEFT JOIN
GLAS_SBLGR_MASTERS m
ON ( c.PC_SL_ACNO = m.SLMA_ACNO
AND c.PC_COMP_CODE = m.SLMA_COMP_CODE
)
LEFT JOIN
GLAS_PTY_ADDRESS a
ON ( m.SLMA_ADDR_ID = a.COAD_ADDR_ID
AND m.SLMA_COMP_CODE = a.COAD_COMP_CODE
AND m.SLMA_ADDR_TYPE = a.COAD_ADDR_TYPE
)
WHERE
c.PC_COMP_CODE = :PARAMETER.COMP_CODE
AND c.PC_SL_ACNO = :BLOCK03.PC_SL_ACNO
AND c.PC_BANK_FROM = :BLOCK02.PB_BANK_CODE
AND NVL(c.PC_DISCD,'X') IN (‘X’, 'R')
AND c.PC_DUE_DATE BETWEEN :BLOCK01.DATE_FROM AND :BLOCK01.DATE_TO
GROUP BY
c.PC_SL_ACNO, -- not sure which grouping exactly you need.
a.COAD_PTY_FULL_NAME
ORDER BY
c.PC_SL_ACNO
I notice that in the first query you have pc_comp_code as a search criterion, and on the leading edge of your grouping - is that what you need?
This is a bit of an 'estimate' due to the enigmatic nature of your question!