Entity framework split DATETIME to sort by TIME only - entity-framework-core

I'm running a query on table which contains a DATETIME column where I want to sort results by TIME only and ignore the date. I've put together the following query;
SELECT DISTINCT s.Id, s.SubmittedDate, s.CheckId, s.RestaurantId, s.StaffName, s.CustomerEmail, s.TableNumber
FROM Survey s
ORDER BY DATEPART (hh,s.submittedDate) ASC, DATEPART(mi,s.submittedDate) ASC
The problem with this query is that it generates the error ORDER BY items must appear in the select list if SELECT DISTINCT is specified. However, I cannot add the order by fields to the field list in the query as it doesn't exist on the Survey Entity that Entity Framework maps the results to.
Is there a way to get around this?

Coming from a Java background, I assumed that Entity Framework would complain if the results returned fields that did not exist on the entity. I tried it and Entity Framework does not complain and it works as expected.
My final working query is;
SELECT DISTINCT s.Id, s.SubmittedDate, s.CheckId, s.RestaurantId, s.StaffName, s.CustomerEmail, s.TableNumber, DATEPART(hh, s.submittedDate) as hrs, DATEPART(mi, s.submittedDate) as mins
FROM Survey s
ORDER BY hrs, mins ASC

Related

How to get latest data for a column when using grouping in postgres

I am using postgres alongside sequelize. I have encountered a case where I need to write a coustom query which groups the records are a particular field. I know for the remaning columns that are not used for grouping, I need to use a aggregate function like SUM. But the problem is that for some columns I need to get the one what is the latest one (DESC sorted by created_at). I see no function in sql to do so. Is my only option to write subqueries or is there a better way? Thanks?
For better understanding, If you look at the below picture, I want the group the records with address. So after the query there should only be two records, one with sydney and the other with new york. But when it comes to the distance, I want the result of the query to contain the distance form the row that was most recently created, i.e with the latest created_at.
so the final two query results should be:
sydney 100 2022-09-05 18:14:53.492131+05:45
new york 40 2022-09-05 18:14:46.23328+05:45
select address, distance, created_at
from(
select address, distance, created_at, row_number() over(partition by address order by created_at DESC) as rn
from table) x
where rn = 1

GROUP BY and ordering by date that was extracted as timestamp

I have a rather simple query:
SELECT table.foo, array_agg([ARRAY[EXTRACT(epoch FROM table.date), table.bar]) AS array
FROM table
GROUP BY table.foo,
ORDER BY table.date ASC;
When I run this query I get an error:
ERROR: column "table.date" must appear in the GROUP BY clause or be used in an aggregate function
I don't quite understand why that is happening because date appears in aggregate function. Is there any way to achieve that grouping?
you cant order by not existing column. If you want to order values in aggregation, use:
SELECT table.foo, array_agg([ARRAY[EXTRACT(epoch FROM table.date), table.bar] ORDER BY table.date ASC) AS array
FROM table
GROUP BY table.foo;

2-steps query in OrientDB

I'm evaluating OrientDB and Neo4j in this simple toy example composed by:
Employees, identified by eid
Meetings, identified by mid and having start and end attributes encoding their start and end DateTime.
Both entities are represented by different classes of vertices, namely Employee and CalendarEvent, which are connected by Involves edges specifying that CalendarEvent-[Involves]->Employee.
My task is to write a query that returns, for each pair of employees, the date/time of their first meeting and the number of meetings they co-attended.
In Cypher I would write something like:
MATCH (e0: Employee)<-[:INVOLVES]-(c:CalendarEvent)-[:INVOLVES]->(e1: Employee)
WHERE e0.eid > e1.eid
RETURN e0.eid, e1.eid, min(c.start) as first_met, count(*) as frequency
I wrote the following query for OrientDB:
SELECT eid, other, count(*) AS frequency, min(start) as first_met
FROM (
SELECT eid, event.start as start, event.out('Involves').eid as other
FROM (
SELECT
eid,
in('Involves') as event
FROM Employee UNWIND event
) UNWIND other )
GROUP BY eid, other
but it seems over-complicated to me.
Does anybody knows if there is an easier way to express the same query?
yes, your query is correct and this is what you have to do in current version (2.1.x).
From 2.2, with MATCH statement (https://github.com/orientechnologies/orientdb-docs/blob/master/source/SQL-Match.md), you will be able to write a query very similar to Cypher version:
select eid0, eid1, min(start) as firstMet, count(*) from (
MATCH {class:Person, as:e0}.in("Involves"){as: meeting}.out("Involves"){as:e1}
return e0.eid as eid0, e1.eid as eid1, meeting.start as start
) group by eid0, eid1
This feature is till in beta, probably in final version you will have more operators in the MATCH statement itself and the query will be even shorter

group by date aggregate function in postgresql

I'm getting an error running this query
SELECT date(updated_at), count(updated_at) as total_count
FROM "persons"
WHERE ("persons"."updated_at" BETWEEN '2012-10-17 00:00:00.000000' AND '2012-11-07 12:25:04.082224')
GROUP BY date(updated_at)
ORDER BY persons.updated_at DESC
I get the error ERROR: column "persons.updated_at" must appear in the GROUP BY clause or be used in an aggregate function LINE 5: ORDER BY persons.updated_at DESC
This works if I remove the date( function from the group by call, however I'm using the date function because i want to group by date, not datetime
any ideas
At the moment it is unclear what you want Postgres to return. You say it should order by persons.updated_at but you do not retrieve that field from the database.
I think, what you want to do is:
SELECT date(updated_at), count(updated_at) as total_count
FROM "persons"
WHERE ("persons"."updated_at" BETWEEN '2012-10-17 00:00:00.000000' AND '2012-11-07 12:25:04.082224')
GROUP BY date(updated_at)
ORDER BY count(updated_at) DESC -- this line changed!
Now you are explicitly telling the DB to sort by the resulting value from the COUNT-aggregate. You could also use: ORDER BY 2 DESC, effectively telling the database to sort by the second column in the resultset. However I highly prefer explicitly stating the column for clarity.
Note that I'm currently unable to test this query, but I do think this should work.
the problem is that, because you are grouping by date(updated_at), the value for updated_at may not be unique, different values of updated_at can return the same value for date(updated_at). You need to tell the database which of the possible values it should use, or alternately use the value returned by the group by, probably one of
SELECT date(updated_at) FROM persons GROUP BY date(updated_at)
ORDER BY date(updated_at)
or
SELECT date(updated_at) FROM persons GROUP BY date(updated_at)
ORDER BY min(updated_at)

sql date order by problem

i have image table, which has 2 or more rows with same date.. now im tring to do order by created_date DESC, which works fine and shows rows same position, but when i change the query and try again, it shows different positions.. and no i dont have any other order by field, so im bit confused on why its doing it and how can i fix it.
can you please help on this.
To get reproducible results you need to have columns in your order by clause that together are unique. Do you have an ID column? You can use that to tie-break:
ORDER BY created_date DESC, id
I suspect that this is happening because MySQL is not given any ordering information other than ORDER BY created_date DESC, so it does whatever is most convenient for MySQL depending on its complicated inner workings (caching, indexing, etc.). Assuming you have a unique key id, you could do:
SELECT * FROM table t ORDER BY t.created_date DESC, t.id ASC
Which would give you the same result every time because putting a comma in the arguments following ORDER BY gives it a secondary ordering rule that is executed when the first ordering rule doesn't produce a clear order between two rows.
To have consistent results, you will need to add at least more column to the 'ORDER BY' clause. Since the values in the created_date column are not unique, there is not a defined order. If you wanted that column to be 'unique', you could define it as a timestamp.