When creating a query in Google Sheets, I'm finding that hardcoding is working fine but using several references isn't working correctly.
Cell A2 = 0.75 (from a formula =(mround(Estimator!$C$4/57.2958,0.25)), type = number)
Cell B2 = 0.9 (from a formula =(mround(Estimator!$C$5+100,0.1)-100) type = number)
Specifically, the query below works:
=query(Time_Data, "SELECT N, O, P WHERE A="0.75" AND B="0.9)
And the query below works:
=query(Time_Data, "SELECT N, O, P WHERE A="&$A$2&" AND B="0.9)
But this query does not work:
=query(Time_Data, "SELECT N, O, P WHERE A="&0.75&" AND B="&$B$2)
And most importantly, this query does not work:
=query(Time_Data, "SELECT N, O, P WHERE A="&$A$2&" AND B="&$B$2)
Any suggestions about how to get this reference to work?
It would help if we could see your data. But maybe try FILTER() and see if that works?
=FILTER(N:P, A:A=A2, B:B=B2)
this is the correct syntax:
=QUERY(Time_Data; "SELECT N, O, P WHERE A matches'"&$A$2&"' AND B matches '"&$B$2&"'")
and if by any chance it wouldn't work try:
=QUERY(Time_Data; "SELECT N, O, P WHERE A matches '"&INDIRECT("A2")&"'
AND B matches '"&INDIRECT("B2")&"'")
I called google support and they advised as follows: the formula in cell B2 was edited from
=(mround(Estimator!$C$5+100,0.1)-100)
to
=Value((mround(Estimator!$C$5+100,0.1)-100))
This resolved the issue.
Related
I am trying to use the COUNT() function inside a nested query for Google Sheets. Here is the query I am using: =query('Salary Data'!B3:J35000, "SELECT '"&query('Salary Data'!B3:J35000, "SELECT COUNT(E) WHERE E >= 1000000")&"', COUNT(E) WHERE E >=900000 AND E < 1000000")
The query outputs 'count' for the result of the nested query instead of the count of salaries >= 1000000. How do I get the actual count from the subquery?
EDIT: It seems the subquery only returns the name of the aggregate function used, whether it is count, max, min, avg, etc.
May be
={query('Salary Data'!B3:J35000, "SELECT COUNT(E) WHERE E > 90000 and E >= 1000000"),query('Salary Data'!B3:J35000, "SELECT COUNT(E) WHERE E >= 1000000")}
I really don't understand what you expect!
Let us consider a simple example with two types of nodes: Company and Worker. For any couple of companies c1 and c2 (which respect some conditions that I will ignore here), I'd need to know: 1. How many workers they have in common, how many workers has c1, and how many workers has c2.
My first guess was :
MATCH (w_c1:Worker)--(c1:Company)--(w_common)--(c2:Company)--(w_c2:Worker)
WHERE <something>
RETURN c1, c2, COUNT(DISTINCT w_common), COUNT(DISTINCT w_c1), COUNT(DISTINCT w_c1)
The problem with that request is that, if I have only one link between any pair of connected nodes, COUNT(DISTINCT w_c1) (id for w_c2) does only count the worker of c1 which are not common with c2. But if I have several relations between some nodes, the results is sometimes "correct". It sounds like the path in the match does not "come back" : (w_common)--(c2:Company)--(w_c2:Worker) will no match ("worker1")--("company2")--("worker1") (which may make sense to avoid infinite loops).
My second guess was to split the request in two parts:
My first guess was :
MATCH (c1:Company)--(w_common)--(c2:Company)
MATCH (c1)--(w_c1:Worker), (c2)--(w_c2:Worker)
WHERE <something>
RETURN c1, c2, COUNT(DISTINCT w_common), COUNT(DISTINCT w_c1), COUNT(DISTINCT w_c1)
But then, the results is correct but I have a warning about cartesian products, and indeed, on big dataset, my request does not complete after hours. I tried with a "WITH c1, w_common, c2" between the two matches, but I still have the warning
How should I proceed ?
One thing that will help you is the SIZE() function, which can tell you the number of occurrences of a pattern, such as the number of :Workers per :Company.
This query may work for you, assuming that a Worker working for a Company only has one relationship to that Company:
MATCH (c1:Company)--(w_common:Worker)--(c2:Company)
WHERE <your criteria for matching on a specific c1 and c2>
RETURN COUNT(w_common) as inCommonCount, SIZE( (c1)--(:Worker) ) as c1Count, SIZE( (c2)--(:Worker) ) as c2Count
You can use sub-totals:
OPTIONAL MATCH (C1:Company {name: 'c1'})
OPTIONAL MATCH (C2:Company {name: 'c2'})
WITH C1, C2
MATCH (C:Company)<-[:workto]-(W:Worker) WHERE C = C1 OR C = C2
WITH C1, C2, W,
sum(CASE WHEN C = C1 THEN 1 ELSE 0 END) as tmp1,
sum(CASE WHEN C = C2 THEN 1 ELSE 0 END) as tmp2
RETURN C1, C2,
sum(tmp1) as cc1, sum(tmp2) as cc2,
sum(tmp1 * tmp2 ) as common
I have what feels like a fairly simple Cypher question.
I have the following data, where I have two A nodes and 3 B nodes with b1 being related to a1, b2 related to a2, and b3 is shared and related to both a1 and a2. My goal is write a Cypher statement that, given a particular A node, will return the B nodes that are connected only to it and are not related with any other A node. For example, when given node a1 the query should return b1 and when given node a2, b2 should be returned. The b3 node, which is relate to both a1 and a2, should never be returned from this query regardless of which A node is specified. Said differently, I am trying to find the B nodes that are unique to a given A node, in that the resulting B nodes are not related to any other A node other than the one specified in my match.
This example data will (hopefully) make my goal more clear:
CREATE (n:A { code: 'a1' })
CREATE (n:A { code: 'a2' })
CREATE (n:B { code: 'b1' })
CREATE (n:B { code: 'b2' })
CREATE (n:B { code: 'b3' })
match (a:A), (b:B) where a.code = 'a1' and b.code = 'b1' create (a)<-[r:A_AND_B]-(b) return a, r, b
match (a:A), (b:B) where a.code = 'a2' and b.code = 'b2' create (a)<-[r:A_AND_B]-(b) return a, r, b
match (a:A), (b:B) where a.code = 'a1' and b.code = 'b3' create (a)<-[r:A_AND_B]-(b) return a, r, b
match (a:A), (b:B) where a.code = 'a2' and b.code = 'b3' create (a)<-[r:A_AND_B]-(b) return a, r, b
If I were willing to include the shared b3 node, the query would be straight forward and be:
match (a:A)-[r:A_AND_B]-(b:B) where a.code = 'a1' return b
This returns b1 and b2. However, given that I do want to include any B nodes that are relate to a different A node (b2 should not be returned in this case), I'm struggling to come up with the right approach and syntax.
I've explored explored Cypher's WITH and OPTIONAL MATCH with so far no luck. I am also able to accomplish what I want if I use two separate queries, which is a bit of a cheat and sidesteps the learning opportunity.
Can someone provide a boost?
How about something like this:
match (a:A)-[:A_AND_B]-(b:B)
where a.code = 'a1'
match (b)-[r:A_AND_B]-(:A)
with b, count(r) as c
where c = 1
return b
I've got a simple graph database which contains two types.
BlogPost
Tag
A BlogPost can have many tags.
I've written a BlogPost and given it 4 tags. I'd like to search for other BlogPosts which contain at least these four tags.
I've tried
MATCH (b:BlogPost{id='156'})-[:tagged]->(original_tag)
WITH b, collect(original_tag) AS original_tags
MATCH (b2)-[:tagged]-(second_blog_tag)
WITH b, original_tags, collect(second_blog_tag) AS second_blog_tags, b2
WHERE original_tags IN second_blog_tags
RETURN b2.id
However the line
WHERE original_tags IN second_blog_tags
is wrong. Can anyone offer any assistance? Is my thinking about using collects correct or is there a better way?
Try this:
MATCH (b:BlogPost{id='156'})-[:tagged]->(original_tag)
WITH b, collect(original_tag) AS original_tags
MATCH (b2)-[:tagged]-(second_blog_tag)
WITH b, original_tags, collect(second_blog_tag) AS second_blog_tags, b2
WHERE ALL(tag IN original_tags WHERE tag IN second_blog_tags)
RETURN b2.id
you can also try:
MATCH (b:BlogPost{id='156'})-[:tagged]->(original_tag)<-[:tagged]-(b2:BlogPost)
WITH b, b2, count(distinct original_tag) as tagCount
WHERE tagCount = size((b)-[:tagged]->())
RETURN b2.id
I'm doing a query like
MATCH (a)
WHERE id(a) = {id}
WITH a
MATCH (a)-->(x:x)-->(b:b)
WITH a, x, b
MATCH (a)-->(y:y)-->(b:b)
WITH a, x, y, b
MATCH (b)-->(c:c)
RETURN collect(a), collect(x), collect(y), collect(b), collect(c)
what I want here is to have the b from MATCH (a)-->(y:y)-->(b:b) to be composed of the ones from that line and the ones from the previous MATCH (a)-->(x:x)-->(b:b). The problem I'm having with UNION is that its picky about the number and kind of nodes to be passed on the next query, and I'm having trouble understanding how to make it all go together.
What other solution could I use to merge these nodes during the query or just before returning them? (Or if should I do it with UNION then how to do it that way...)
(Of course the query up there could be done in other better ways. My real one can't. That is just meant to give a visual example of what I'm looking to do.)
Much obliged!
This simplified query might suit your needs.
I took out all the collect() function calls, as it is not clear that you really need to aggregate anything. For example, there will only be a single 'a' node, so aggregating the 'a's does not make sense.
Please be aware that every row of the result will be for a node labelled either 'x' or 'y'. But, since every row has to have both the x and y values -- every row will have a null value for one of them.
START a=node({id})
MATCH (a)-->(x:x)-->(b:b)-->(c:c)
RETURN a, x, null AS y, b, c
UNION
MATCH (a)-->(y:y)-->(b:b)-->(c:c)
RETURN a, null AS x, y, b, c
The best solution I could come up in the end was something like this
MATCH (a)-->(x:x)-->(b1:b)-->(c1:c)
WHERE id(a) = {id} AND NOT (a)-->(:y)-->(b1)
WITH a, collect(x) as xs, collect(DISTINCT b1) as b1s, collect(c1) as c1s
MATCH (a)-->(y:y)-->(b2:b)-->(c2:c)
RETURN a, xs, collect(y), (b1s + collect(b2)), c1s + collect(c2)