I have this query for filtering a sheet by multiple criteria:
=query(A2:H,"select A,B,C,D,E,F,G "&IF(K3="where","","where A >= date '"&TEXT(K3,"yyyy-mm-dd")&"'")&"
"&IF(K4="","","and A <= date '"&TEXT(K4,"yyyy-mm-dd")&"'")&"
"&IF(K5="","","and B matches '"&UPPER(K5)&"'")&"
"&IF(K6="","","and C matches '"&UPPER(K6)&"'")&"
",1)
It works fine but, when all the arguments return false, I get the whole range, presumably as the query becomes just select A,B,C,D,E,F,G.
Is there any way I can force it to return nothing, or an error even. I Tried just putting a random OR C matches 'nothing' at the end but it still returned everything.
Chris, you could put an IF statement around the whole QUERY. Something like:
=IF(AND(K3="where",K4="",K5="",K6=""),"",QUERY(....))
Would that work for you?
Related
we are trying to run a cypher query but we are not able to get the results we want.
It is important to note that we cannot make this work with subqueries because we are using Neo4j 3.5 and in this version, they are still not available.
The problem is that we have two parts for a query, the first one will fix the variables for the second part, and the second part consists of multiple matches, and it has to get the results of the previous query and if at least one of the matches return a result for a row, this row is not filtered out, else if none return result it is discarded.
More specifically, the query we are trying to run is similar to the following one:
//First part of the query where we want to fix variables with the match and where
MATCH (u:User)-[:ASSIGNED_TO]->(t:Task)-[:PENDING]->(ob:Object)<-[:HAS_OPEN_OBJECT]-(do:DataObject)<-[:ASOCIATED]-(:Module)-[:CAN_LIST]->(view:WidgetObject)
WHERE u.uid = 'user_uid'
AND view.uid = 'view_uid'
AND view.object_name = do.object_type
with do, t, ob
// In this second part of the query we want to maintain the variables of the previous part and if at least one matches the value should be returned
// we have tried with UNION but we will need pagination, but even with union it's not working
MATCH (ac:Action)<-[:ASOCIATED]-(t)-[rel:COMPLETED|PENDING]->(ob)<-[:HAS_OPEN_OBJECT|HAS_CLOSED_OBJECT]-(do)
WHERE ac.name CONTAINS 'body'
WITH COLLECT({data_object_uid: do.uid}) as act_filter
MATCH (c:Comment)<-[:COMMENTED]-(t)-[rel:COMPLETED|PENDING]->(ob)<-[:HAS_OPEN_OBJECT|HAS_CLOSED_OBJECT]-(do)
WHERE c.body CONTAINS 'body'
WITH act_filter + COLLECT({data_object_uid: do.uid}) as comment_filter
MATCH (at:Attachment)<-[:HAS_ATTACHMENT]-(t)-[rel:COMPLETED|PENDING]->(ob)<-[:HAS_OPEN_OBJECT|HAS_CLOSED_OBJECT]-(do)
WHERE at.name CONTAINS 'body'
WITH comment_filter + COLLECT({data_object_uid: do.uid}) as attachment_filter
UNWIND attachment_filter as row
return row.data_object_uid
We are not sure if in the second part, the second and third matches are maintaining the same subset of results coming from the first part of the query.
A funny behavior we have found is that if we remove the last match we are getting results but if we add it, we are not getting any results. We do not understand this behavior because if the second match is returning results and they are stored in a variable after a collect, appending this to the next collected results should return something.
For example, if the second match returns as comment_filter [{data_object_uid: "343dienmd3-dasd"}] and the third match is not returning anything, after the concatenation in the WITH clause it should return the same thing, but the result is empty.
We need some light here, we don't know if we are close and we are making a stupid mistake or we are getting all wrong and we need to change the approach completely.
Since you do not know which of the three matches in the second part will yield results, I would try something along the lines below:
NOTE I used ASSOCIATED instead of ASOCIATED
MATCH (n)<-[:ASSOCIATED|COMMENTED|HAS_ATTACHMENT]-(t)-[rel:COMPLETED|PENDING]->(ob)<-[:HAS_OPEN_OBJECT|HAS_CLOSED_OBJECT]-(do)
WHERE
(n:Action AND n.name CONTAINS 'body')
OR
(n:Comment AND n.body CONTAINS 'body')
OR
(n:Attachment AND n.name CONTAINS 'body')
RETURN COLLECT(DISTINCT {data_object_uid: do.uid})
I have a field in the database which contains strings that look like: 58XBF2022L1001390 I need to be able to query results which match the last letter(in this case 'L'), and match or resemble the last four digits.
The regular expression I've been using to find records which match the structure is: \d{2}[A-Z]{3}\d{4}[A-Z]\d{7}, So far I've tried using a scope to refine the results, but I'm not getting any results. Here's my scope
def self.filter_by_shortcode(input)
q = input
starting = q.slice!(0)
ending = q
where("field ~* ?", "\d{2}[A-Z]{3}\d{4}/[#{starting}]/\d{3}[#{ending}]\g")
end
Here are some more example strings, and the substring that we would be looking for. Not every string stored in this database field matches this format, so we would need to be able to first match the string using the regex provided, then search by substring.
36GOD8837G6154231
G4231
13WLF8997V2119371
V9371
78FCY5027V4561374
V1374
06RNW7194P2075353
P5353
57RQN0368Y9090704
Y0704
edit: added some more examples as well as substrings that we would need to search by.
I do not know Rails, but the SQL for what you want is relative simple. Since your string if fixed format, once that format is validated, simple concatenation of sub-strings gives your desired result.
with base(target, goal) as
( values ('36GOD8837G6154231', 'G4231')
, ('13WLF8997V2119371', 'V9371')
, ('78FCY5027V4561374', 'V1374')
, ('06RNW7194P2075353', 'P5353')
, ('57RQN0368Y9090704', 'Y0704')
)
select substr(target,10,1) || substr(target,14,4) target, goal
from base
where target ~ '^\d{2}[A-Z]{3}\d{4}[A-Z]\d{7}$';
MATCH (a:Chemical{name:'abc'})-[r:On_Reacting_With]->(b:Chemical)
WHERE r.outputtime >'20'
RETURN count(b)
As in the above query I can get values where the outputtime is greater than 20. But I want to give the user a feature where he/she can fetch the data where outoutime can be greater, lesser or equal to a value. I want to know how can we pass the operator as params in code.
Aside: using string values for time comparison will not produce correct results unless all strings have the same length (including leading zero characters, as needed).
You can pass in an operator parameter and use a CASE clause. For instance:
MATCH (a:Chemical{name:'abc'})-[r:On_Reacting_With]->(b:Chemical)
WHERE
CASE $operator
WHEN '<' THEN r.outputtime < '20'
WHEN '>' THEN r.outputtime > '20'
ELSE r.outputtime = '20'
END
RETURN COUNT(b)
I not sure if I understand how FILTER is working.
I would like to SUM only the results that satisfy both conditions in the FILTER and get 8+10=18, but it seems I'm getting 8+9+10=27 as if the first condition is ignored.
Both =SUM(FILTER(E1:E10,MATCH(D1:D10, G1:G4), E1:E10 > 7)) and =SUM(FILTER(E1:E10,MATCH(D1:D10, G1:G4) * (E1:E10 > 7))) return 27
Have any ideas?
Here is an example and a screenshot
The crucial thing is putting the third argument into the Match function to specify an exact match
=SUM(FILTER(E1:E10,MATCH(D1:D10, G1:G4,0), E1:E10 > 7))
Otherwise you get the position of the largest value less than or equal to the lookup value: e.g. for "G" you would get a match with "D" which would return 4. So the Match function in your original formula always returns a number >=1 which is treated as True.
It's interesting that the above formula works actually because a non-match will return #N/A but apparently it's treated as false - I don't know if this is documented.
I would always put
=SUM(FILTER(E1:E10,isnumber(MATCH(D1:D10, G1:G4,0)), E1:E10 > 7))
to make it clearer.
what i'm trying to do is to Sum the total deposits of each reservation model, with the condition of less than the amount input in the text.
here's my query:
$reservations->whereHas('deposits', function($query) use ($etc_filters){
$query->havingRaw('SUM(amount) <= '.$etc_filters);
});
as you can see, i'm using havingRaw that can be injected with another query. right now i cant find any alternative solution for my code.
You can use the second argument the havingRaw method accepts, to make the value a binding, which gets escaped before it is inserted in the query:
$reservations->whereHas('deposits', function($query) use ($etc_filters){
$query->havingRaw('SUM(amount) <= ?', $etc_filters);
});