How to convert mysql query to JPQL query - mysql

I have working MySQL query:
SELECT date(timestamp), hour(timestamp), sum(numberDet), count(*)
FROM human_det_counter
GROUP BY hour( timestamp ) , day( timestamp )
ORDER BY date(timestamp)
I want select records, group by hour from each day and sum their number of detections.
I have tried this query:
SELECT date(h.timestamp), hour(h.timestamp), sum(h.numberDet), count(h)
FROM HumanDetCounter h
GROUP BY hour( h.timestamp ) , day(h.timestamp )
ORDER BY date(h.timestamp)
,but it's not working. I readed that jpa don't support Hour() function and that I should use TO_CHART function, but I don't know how.

Okey, I figured it out. There's my query if someone needs that:
createQuery("SELECT cast(Date(h.timestamp) as string), substring(h.timestamp, 12,2) , sum(h.numberDet), count(h) FROM HumanDetCounter h GROUP by substring(h.timestamp, 12,2), substring(h.timestamp, 9,2) ORDER BY h.timestamp")
It's probably not the best solution, but it's work :)

Related

Group by help ( grouping by multiple, have duplicates)

SO i have a task and i need to group my results by Date and by Provider_name but currently my code is listing out multiple dates and Providers. (need to have one provider per day (25 days in all) so my table shows how many messages the provider got that day and how much did they earn)
This needs to be my result. Result table
But this is what i'm currently getting
This is my code currently
SELECT date_format( time, '%Y-%m-%d' ) AS Date, provider_name, COUNT( message_id ) AS Messages_count, SUM( price ) AS Total_price
FROM mobile_log_messages_sms
INNER JOIN service_instances ON service_instances.service_instance_id = mobile_log_messages_sms.service_instance_id
INNER JOIN mobile_providers ON mobile_providers.network_code = mobile_log_messages_sms.network_code
WHERE time
BETWEEN '2017-02-26 00:00:00'
AND time
AND '2017-03-22 00:00:00'
AND price IS NOT NULL
AND price <> ''
AND service IS NOT NULL
AND service <> ''
AND enabled IS NOT NULL
AND enabled >=1
GROUP BY provider_name, time
ORDER BY time DESC
Can you tell me where i've messed up, i really can't figure out the answer.
Try like this:
....
GROUP BY provider_name, date_format( time, '%Y-%m-%d' )
ORDER BY time DESC
You are grouping time which will group the result by time including hour, minute and second so on ... that is why you getting different count from same day. Try grouping by day instead.
time column is datetime. So its grouped by date and time both rather than just date.
Change GROUP BY statement to
GROUP BY provider_name, date_format( time, '%Y-%m-%d' )

Reverse order for GROUP BY in MySQL

I need to select first value for every hour from my db. But I don't know how to reverse order on GROUP BY statement.
How can i rewrite my query (now it selects last value in hour)?
SELECT HOUR(`time`) as hour, mytable.*
FROM mytable
WHERE DATE(`time`) ="2015-09-12" GROUP BY HOUR(`time`) ORDER BY `time` ASC;
This query gave me expected result:
SELECT HOUR(`time`) as hour, sortedTable.* FROM
(SELECT electrolysis.* FROM electrolysis
WHERE DATE(`time`)='2015-09-12' ORDER BY `time`) as sortedTable
GROUP BY HOUR(`time`);
You can just select the MIN HOUR in sub query , try using the query:
SELECT * from mytable WHERE `time` IN (
SELECT MIN(HOUR(`time`)) as `hour`
FROM mytable
WHERE DATE(`time`) ="2015-09-12"
GROUP BY HOUR(`time`) ) ORDER BY `time` ASC;
You can do something like this:-
SELECT sub0.min_time,
mytable.*
FROM mytable
INNER JOIN
(
SELECT MIN(`time`) AS min_time
FROM mytable
GROUP BY HOUR(`time`)
) sub0
ON mytable.`time` = sub0.min_time
WHERE DATE(`time`) ="2015-09-12"
ORDER BY `time` ASC
This is using a sub query to get the smallest time in each hour. This is then joined back against your main table on this min time to get the record that has this time.
Note that there is a potential problem here if there are multiple records that share the same time as the smallest one for an hour. There are ways around this, but that will depend on your data (eg, if you have a unique id field which is always ascending with time then you could select the min id for each hour and join based on that)
You can use below query, which is more optimized just make sure that time field should be indexed.
SELECT HOUR(m.time), m.*
FROM mytable AS m
JOIN
(
SELECT MIN(`time`) AS tm
FROM mytable
WHERE `time` >= '2015-09-12 00:00:00' AND `time` <= '2015-09-12 23:59:59'
GROUP BY HOUR(`time`)
) AS a ON m.time=a.tm
GROUP BY HOUR(m.time)
ORDER BY m.time;

date_trunc PostgreSQL function equal for mySQL

Im trying to retrieve data to make statistics, im using mySQL and i cant get the following function to work - the postgreSQL is working.
I want to retrieve the request for the last month and count the amount of new requests for each day.
postgreSQL
SELECT count(*), date_trunc('day', created_at) as date FROM requests
WHERE(created_at > '2014-08-13 00:00:00') GROUP BY 2 ORDER BY 2 ASC;
*mySQL - my code *
SELECT count(EXTRACT(DAY FROM created_at)), EXTRACT(DAY FROM created_at) as date
FROM `requests`
WHERE EXTRACT(DAY FROM NOW() - INTERVAL 1 MONTH)
GROUP BY date
Final code
SELECT count( * ) , date( created_at ) AS date
FROM `requests`
WHERE DATE( created_at ) > DATE( DATE_SUB( NOW( ) , INTERVAL 1 MONTH ) )
GROUP BY date
The equivalent for your case is date():
select date(created_at), count(*)
from requests
. . .
This isn't a general replacement, but it works to remove the time portion of a date.
EDIT:
Perhaps the better solution for these two databases is:
select cast(created_at as date)
This is ANSI standard and works in both these databases (as well as SQL Server). I personally don't use this in general, lest I accidentally use it in Oracle, causing difficult to find errors. (dates in Oracle have a time component, alas.)

How to resolve issue in order by date

SELECT COUNT(patient_id) AS idpateint,
patient_id
FROM patient
WHERE STR_TO_DATE(date_enter,'%d/%m/%Y' )
BETWEEN STR_TO_DATE( '$repeat','%d/%m/%Y' ) AND STR_TO_DATE('$to','%d/%m/%Y')
AND patient_type='opd'
AND patient_id ='$idpatient1'
ORDER BY STR_TO_DATE(date_enter,'%d/%m/%Y' )
Actually I saved date in dd/mm/yyyy format in db. Order by is not working. No SQL error but date is not coming in order.
Here is your query:
select count(patient_id) as numpatients, patient_id
from patient
where STR_TO_DATE(date_enter, '%d/%m/%Y' ) between STR_TO_DATE('$repeat', '%d/%m/%Y' ) and
STR_TO_DATE('$to', '%d/%m/%Y') and
patient_type = 'opd' and
patient_id = '$idpatient1'
order by STR_TO_DATE(date_enter, '%d/%m/%Y' )
You have a count() in the select. This turns the query into an aggregation query, so it only returns one row. In addition, you are selectxing only a single patient id. I could imagine that you want the counts by date, because you are so focused on date.
The following will give counts by date, regardless of the patient:
select STR_TO_DATE(date_enter, '%d/%m/%Y' ), count(patient_id) as numpatients
from patient
where STR_TO_DATE(date_enter, '%d/%m/%Y' ) between STR_TO_DATE('$repeat', '%d/%m/%Y' ) and
STR_TO_DATE('$to', '%d/%m/%Y') and
patient_type = 'opd' and
group by STR_TO_DATE(date_enter, '%d/%m/%Y' )
order by STR_TO_DATE(date_enter, '%d/%m/%Y' );
By the way. Don't you think the query looks ugly with all those calls to STR_TO_DATE(). They are ugly in addition to making the query less efficient. Store dates in the database using the database data types. That is what they are there for.

MySQL: Getting "busiest" or "most popular" hour from a datetime field?

Consider the following table which has the fields - id (int) and date_created (datetime):
id date_created
1 2010-02-25 12:25:32
2 2010-02-26 13:40:37
3 2010-03-01 12:02:22
4 2010-03-01 12:10:23
5 2010-03-02 10:10:09
6 2010-03-03 12:45:03
I want to know the busiest/most popular hour of the day for this set of data. In this example, the result I'm looking for would be 12.
Ideas?
To get just the most popular hour, use this query
select date_format( date_created, '%H' ) as `hour`
from [Table]
group by date_format( date_created, '%H' )
order by count(*) desc
limit 1;
If you want to look at all the data, go with this one
select count(*) as num_records
, date_created
, date_format( date_created, '%H' ) as `hour`
from [Table]
group by `hour`
order by num_records desc;
If you want something a little more flexible, perhaps to the half hour, or quarter hour, you can do the following:
SELECT floor(time_to_sec(date_created)/3600),count(*) AS period
FROM table GROUP BY period ORDER BY c DESC
If you want the most popular 2 hour interval, use 7200. The most popular 15 minute interval, use 900. You just need to remember you are dealing with seconds (3600 seconds in an hour).
Use the hour() function to extract the hour, then do the usual aggregation:
SELECT count(hour(date_created)) AS c, hour(date_created) AS h FROM table GROUP BY h ORDER BY c DESC;
I like both Simon and Peter's answers, but I can't select both as accepted. I combined the 2 to make a cleaner query that only returned the popular hour (I don't need the counts).
SELECT hour(date_created) AS h
FROM my_table
GROUP BY h
ORDER BY count(*) DESC
LIMIT 1
You could try this:
SELECT
DATE_FORMAT(date,'%H') as hours,
count(*) as count
FROM
myTable
GROUP BY
hours
ORDER BY
count DESC