multiple filters vs OR , ndb query - google-app-engine

What is the difference between these queries:
With consequent filters:
qry1 = Account.query() # Retrieve all Account entitites
qry2 = qry1.filter(Account.userid >= 40) # Filter on userid >= 40
qry3 = qry2.filter(Account.userid < 50) # Filter on userid < 50 as well
Using ndb.OR:
qry = Article.query(ndb.OR(Account.userid >= 40,
Account.userid < 50))
Using ndb.AND:
qry = Article.query(ndb.AND(Account.userid >= 40,
Account.userid < 50))

The first query does an AND. Thus, only the entities that match both inequalities will be returned by the query. The second query does an OR. Thus, entities that match either of the filters will be returned. For more information about ndb queries, take a look at NDB Queries.

Third and the First query are exactly identical. But the second query is absurd, it may end up returning all Entities in the Kind.

Related

Why case..when get a table scan ? how to workarround

When I use CASE .. WHEN .. END I get an index scan less efficient than the index seek.
I have complex business rules I need to use the CASE, is there any workaround ?
Query A:
select * from [dbo].[Mobile]
where((
CASE
where ([MobileNumber] = (LTRIM(RTRIM('987654321'))))
END
) = 1)
This query gets an index scan and 199 logical reads.
Query B:
select * from [dbo].[Mobile]
where ([MobileNumber] = (LTRIM(RTRIM('987654321'))))
This query gets an index seek and 122 logical reads.
For the table
CREATE TABLE #T(X CHAR(1) PRIMARY KEY);
And the query
SELECT *
FROM #T
WHERE CASE WHEN X = 'A' THEN 1 ELSE 0 END = 1;
It is apparent without that much thought that the only circumstances in which the CASE expression evaluates to 1 are when X = 'A' and that the query has the same semantics as
SELECT *
FROM #T
WHERE X = 'A';
However the first query will get a scan and the second one a seek.
The SQL Server optimiser will try all sorts of relational transformations on queries but will not even attempt to rearrange expressions such as CASE WHEN X = 'A' THEN 1 ELSE 0 END = 1 to express it as an X = expression so it can perform an index seek on it.
It is up to the query writer to write their queries in such a way that they are sargable.
There is no workaround to get an index seek on column MobileNumber with your existing CASE predicate. You just need to express the condition differently (as in your example B).
Potentially you could create a computed column with the CASE expression and index that - and you could then see an index seek on the new column. However this is unlikely to be useful to you as I assume in reality the mobile number 987654321 is dynamic and not something to be hardcoded into a column used by an index.
After cleaning up and fixing your code, you have a WHERE which is boolean expression based around a CASE.
As mentioned by #MartinSmith, there is simply no way SQL Server will re-arrange this. It does not do the kind of dynamic slicing that would allow it to re-arrange the first query into the second version.
select *
from [dbo].[Mobile]
where
CASE
WHEN [MobileNumber] = LTRIM(RTRIM('987654321'))
THEN 1
END
= 1
You may ask: the second version also has an expression in it, why does this not also get a scan?
select *
from [dbo].[Mobile]
where [MobileNumber] = LTRIM(RTRIM('987654321'))
The reason is that what SQL Server can recognize is that LTRIM(RTRIM('987654321')) is a deterministic constant expression: it does not change depending on runtime settings, nor on the result of in-row calculations.
Therefore, it can optimize by calculating it at compile time. The query therefore becomes this under the hood, which can be used against an index on MobileNumber.
select *
from [dbo].[Mobile]
where [MobileNumber] = '987654321'

What is wrong with this expressions? =CountRows(ReportItems!Textbox58.Value = "Intervene"). I want to count each row which says Intervene

What is wrong with this expression? =CountRows(ReportItems!Textbox58.Value = "Intervene")
I want to count each row which says Intervene.
As Larnu has commented, you cannot use CountRows against the ReportItems collection.
Probably what you need to do is
Look at the expression in Textbox58 and see where it gets it's data from. In this exmaple let's say it comes from Fields!myFieldName.Value.
Now we need to count the rows where Fields!myFieldName.Value = "Intervene" but rather than using count, we can convert these matches to return 1 or 0 where the field is not "Intervene"
So the expression would look something like this
=SUM(IIF(Fields!myFieldName.Value = "Intervene", 1, 0))
This will sum the rows withing the current scope, so if this is contained in a row group for example, then it will only sum those rows in that row group.
If you need to count based on a a different scope (e.g. the entire dataset) then you can specify that in the SUM() function like this
=SUM(IIF(Fields!myFieldName.Value = "Intervene", 1, 0), "DataSet1")
Here we are summing across the entire dataset where the dataset name is DataSet1
Update based on OP comment
As your expression is
=SUM(IIF(Fields!Actual_Duration.Value >= 10, "Intervene", "No Intervention Needed"))
What we actually need to count is instances where Actual_Duration is >= 10.
So the final expression should be
=SUM(IIF(Fields!Actual_Duration.Value >= 10, 1, 0))

Google Sheets Query - Not like partial match

So I have this formula, and it's working as intended but I would like to further refine the data.
Formula:
=QUERY('Users'!A1:Q, "Select A,B,C,F,G,O,Q where Q >= 180 and Q < 44223")
I have tried:
=QUERY('Users'!A1:Q, "Select A,B,C,F,G,O,Q where Q >= 180 and Q < 44223 and F not like '*text*'")
But that caused an error. Ideally, I would like to ommet any results that match partial texts in columns C and F. Any ideas?
EDIT:
Included a link to an example sheet
Ideally, I want the query to match everything in column F except 'Archived' (but needs to be wildcarded) and everything in column C except Delta (again, needs to be wildcarded)
try:
=QUERY(Sheet1!A1:Q6,
"select A,B,C,F,G,O,Q
where Q >= 180
and Q < 44223
and not lower(O) matches '.*archived.*'
and not lower(C) matches '.*delta.*'")

cakephp : Sort ASC but with 0 value at end

In a find request, how can I sort numeric value in ascending order but having the 0 value at end ?
I want : [2,5,7,7,0,0]
$this->Resuls->find()
->order(['Resuls.sec'=>'asc']);
Thanks
Depending on the DBMS there's various ways to achieve this.
A way that should work on all DBMS supported by CakePHP would probably be to use a CASE statement to first order the rows where Resuls.sec is 0 to the back, and after that order ascending by Resuls.sec regulary, that should get you the results that you are looking for.
$query = $this->Resuls->find();
$zeroLastCase = $query->newExpr()->addCase(
[$query->newExpr()->add(['Resuls.sec' => 0])],
[1, 0],
['integer', 'integer']
);
$query
->orderAsc($zeroLastCase)
->orderAsc('Resuls.sec');
That would generate an ORDER BY clause similar to:
ORDER BY
CASE WHEN Resuls.sec = 0 THEN 1 ELSE 0 END ASC,
Resuls.sec ASC
See also
Cookbook > Database Access & ORM > Query Builder > Case statements
API > \Cake\Database\Query::order()

Question about Solr and SolrJ range query?

Suppose that my index has 3 fields: title, x and y.
I know one range(10 < x < 100) can query like this:
http://localhost:8983/solr/select?q=x:[10 TO 100]&fl=title
If I want to two range(10 < x <100 AND 20 < y < 300) query like
SQL(select title where x>10 and x < 100 and y > 20 and y < 300)
by using Solr range query or SolrJ, but I don't know how to implement this. Does anybody else know? Thanks
Email: enzhaohoo#gmail.com
Take a look at the docs for SolrJ. Successive calls to addFilterQuery will continue to build up your query. Alternatively you can have two things in one fq:
http://localhost:8983/solr/select?q=&fq=x:[10+TO+100]+AND+y:[20+TO+300]&fl=title
There is a method in class SolrQuery can solve your problem,
setFilterQueries(String... fq)
You can take a look at this.

Resources