Compare the value of 2 rows in 1 query - entity-framework

I have a table structure is like this:
USERID int
LOGIN_DATE DateTime
LOGOUT_DATE DateTime
LOGIN_STATUS varchar(10)
The requirement is to retrieve the top 2 rows for a particular USERID sorted by LOGIN_DATE ASC. Then compare the 2 LOGIN_DATE records and check if they are less than 5 minutes.
Can this be done in a single LINQ statement?
Thanks
Parameswaran

Something like this should work (untested)
bool isRecentLogIn = db.Users
.OrderBy(u => u.LOGIN_DATE)
.Take(2)
.All(u => u.LOGIN_DATE.AddMinutes(5) < DateTime.Now);

Related

Postgresql: how to query hstore dynamically

I have the following tables
ORDER (idOrder int, idCustomer int) [PK: idOrder]
ORDERLINE (idOrder int, idProduct int) [PK: idOrder, idProduct]
PRODUCT (idProduct int, rating hstore) [PK: idProduct]
In the PRODUCT table, 'rating' is a key/value column where the key is an idCustomer, and the value is an integer rating.
The query to count the orders containing a product on which the customer has given a good rating looks like this:
select count(distinct o.idOrder)
from order o, orderline l, product p
where o.idorder = l.idorder and l.idproduct = p.idproduct
and (p.rating->(o.idcust::varchar)::int) > 4;
The query plan seems correct, but this query takes forever. So I tried a different query, where I explode all the records in the hstore:
select count(distinct o.idOrder)
from order o, orderline l,
(select idproduct, skeys(p.rating) idcustomer, svals(p.rating) intrating from product) as p
where o.idorder = l.idorder and l.idproduct = p.idproduct
and o.idcustomer = p.idcustomer and p.intrating > 4;
This query takes only a few seconds. How is this possible? I assumed that exploding all values of an hstore would be quite inefficient, but it seems to be the opposite. Is it possible that I am not writing the first query correctly?
I'm suspecting it is because in the first query you are doing:
p.rating->(o.idcust::varchar)::int
a row at a time as the query iterates over the rest of the operations, whereas in the second query the hstore values are expanded in a single query. If you want more insight use EXPLAIN ANALYZE:
https://www.postgresql.org/docs/12/sql-explain.html

how to filter data array_agg from postgresql

I have view at postgres db from this query
SELECT order_product.order_id,
array_agg(order_product.product_id) AS itemset
FROM order_product
GROUP BY order_product.order_id
ORDER BY order_product.order_id;
and this is the structure look like:
And the question is, how can U filter data at (itemset) just show where the value is more than 1 (example: don't show = {8}, just show the value when containing 2 data or more like this = {8,10})
Use the having() clause:
SELECT op.order_id,
array_agg(op.product_id) AS itemset
FROM order_product op
GROUP BY op.order_id
HAVING count(*) > 1 --<< here
ORDER BY op.order_id;

How to catch null while summarizing records in EF6

next problem with Linq/EF6 queries.
I simply like to build a sum of some decimal fields:
var offsetHours1 = (from os in db.TimesheetOffsets
where (os.EmployeeId == employeeId && os.OffsetDate <= DateTime.Today)
select new
{
offset = os.OffsetHours
}).Sum(h=>h.offset);
So far it works, if I have records to sum but if the query returns null or no records, I get a System.InvalidOperationException
Is there an elegant way to summarize records in one step, so if there are no records, 0 is returned?
Thanks, Carsten
There's a quirk with the Sum extension method. As OffsetHours is a decimal, the overload of Sum you'll be using is Sum(..., decimal) which has this behaviour. To avoid it you can cast the value to a decimal? (nullable). With this you'll be using a different Sum that returns a nullable decimal and is OK with empty lists;
You can for example do this;
var offsetHours1 = (from os in db.TimesheetOffsets
where (os.EmployeeId == employeeId && os.OffsetDate <= DateTime.Today)
select os.OffsetHours)
.Sum(h => (decimal?)h);
Edit:
Removed unnecessary creation of anonymous type.

join and count query in flutter sqflite

I have 2 tables one with names and id's and another with id's and dates,
I am trying to figure out how to create the helper method to query the two tables and return the list of names with the number of dates associated to their id.
Name Table
id Name
1 John
2 Tom
3 Frank
Date Table
id Date
1 1/3/19
1 1/4/19
1 1/5/19
2 1/4/19
Results:
Name Count
John 3
Tom 1
Frank 0
This is as far as I have gotten just pulling back all the names.
Future<List> queryAllNames() async {
Database db = await database;
List<Map> names =
await db.query(Names, columns: [id, Name]);
if (names.length > 0) {
return names;
}
return null;
}
I have figured out the raw query I need from sqlite
select Name.name, count(Date.date) from Name left join Date using(id) group by Name.name;
But still not able to translate to at sqflite helper method.
There is a rawQuery() method. Check out Raw SQL queries

how to get records from an specific ID calculated from date?

I have many records that has a datetime field:
MyTable(ID, StartDate,...)
And I have as parameter a startDate, I would like to get all the records that have a startDate >= than the date set in the parameter and also I would like the record which ID is ID -1 of the ID of the first record which startDate >= of the date of the parameter (first record when the result is ordered by date).
Something like that:
dbContext.MyTable.Where(x => x.ID >= dbContext.MyTable.OrderBy(y => y.StartDate).Where(y => y.StartDate >= myDate).First()).ToList();
But I get an error because I can't use First() in this place.
Also if I would use it, first execute the query to the database, but I don't want to do it at this point, because I am constructing a dynamic query and I only want one trip to the database.
So I would like to know if it is possible to use as condition the first element of a result.
Thanks.
You can use Take(1) as replacement of First.
dbContext.MyTable
.Where(x =>
dbContext.MyTable
.OrderBy(y => y.StartDate)
.Where(y => y.StartDate >= myDate)
.Take(1)
.Any(y => x.ID >= y.ID))
.ToList();