Does any way to get the last inserted values in each days - mysql

id date calls
5 2015-02-17 01:06:01 1
6 2015-02-17 11:07:01 2
7 2015-02-17 23:06:01 3
8 2015-02-18 03:07:01 1
9 2015-02-18 09:06:01 2
10 2015-02-18 17:07:01 3
11 2015-02-18 22:06:01 4
12 2015-02-19 01:07:01 1
13 2015-02-19 08:06:01 2
14 2015-02-19 18:07:01 3
15 2015-02-19 23:06:01 4
my table structure is like this and I need to calculate the sum of call in each days. In this table, you can see that, the last call in feb 17 was at 23:06:01 and call count was 3. In feb 18 was at 22:06:01 and call count was 4. Can I get the sum of all this last call counts of each day.

You can use a subquery to determine which rows to sum (the ones matching the last call for each date, using MySQL it would be:
select sum(calls) sum_last_calls
from your_table
where `date` in (
select max(date) max_date
from your_table
group by date(`date`)
)
This query will return 11 as the sum (from 3+4+4).
The date() function used in the subquery is specific to your database and might need to be changed according to your specific database syntax - the point is that it should return the date without time (it could be date::date (Postgresql) or cast(date as date) (MSSQL and others)).
Sample SQL Fiddle for MySQL and Postgresql

Postgresql version:
select sum(calls) as calls
from (
select max(calls) as calls
from t
where date::date between '2015-02-17' and '2015-02-19'
group by date::date
) s

Related

Mysql: How to check validity of order based on dates

Here is a sample data:
Key Start Date Stop date Order
1 2010-07-10 11:50:11 2011-10-20 9:10:59 1
1 2013-01-09 13:04:12 2013-03-11 13:42:25 2
1 2014-05-23 14:45:40 2015-10-16 8:53:54 3
1 2013-01-09 13:04:12 9999-12-31 0:00:00 4
2 2015-12-15 11:16:06 2016-12-15 11:16:06 1
2 2016-12-15 11:16:06 2017-12-15 11:16:06 2
2 2017-12-15 11:16:06 9999-12-31 0:00:00 3
I want to check whether the start and stop dates of a particular order do not invalidate another order for the same key. Only one order is possible within a start and stop range of date.
I want to write a MySQL query to print the key of all which have invalid order.
Here in this example Key one has an invalid order as Order 2 and Order 4 are invalid. Is it possible to check this by MySQL query?
I think you can get the rows that are out of order using:
select s.*
from sample s
where exists (select 1
from sample s2
where s2.key = s.key and
s2.startdate < s.startdate and
s2.order > s.order
);
Note that order and key are SQL keywords, so they are very poor choices for column names.

Mysql get user list of every week interval

I want to write query to fetch user from table who register before week interval.
For ex. todays date is 2017-08-17, then I need user who register on 2017-08-10, 2017-08-03,2017-07-27 and so on. Like this if todays date is 2017-08-20 then user will be register on 2017-08-13, 2017-08-06.
id name date
1 ABC 2018-08-16
2 PQR 2018-08-10
3 LMN 2018-07-27
4 AAA 2018-01-01
Output will be
id name date
2 PQR 2018-08-10
3 LMN 2018-07-27
One way to express this problem is to recognize that we want to retain dates whose difference from today are multiple of 7 days. We can compare the UNIX timestamps of each record and check to see if the number of seconds, when divided by the number of seconds in 7 days, is zero.
SELECT *
FROM yourTable
WHERE
MOD(UNIX_TIMESTAMP(CURDATE()) -
UNIX_TIMESTAMP(DATE(reg_date)), 7*24*60*60) = 0
Demo here:
Rextester
SELECT * FROM user WHERE WEEKDAY(`date`) = WEEKDAY(NOW());
This will get you all users that registered 0, 7, 14, 21 etc. days ago.

Converting the result of a MySQL table as per requirement

The mysql table we work on has data in the following format:
entityId status updated_date
-------------------------------
1 1 29/05/2017 12:00
1 2 29/05/2017 03:00
1 3 29/05/2017 07:00
1 4 29/05/2017 14:00
1 5 30/05/2017 02:00
1 6 30/05/2017 08:00
2 1 31/05/2017 03:00
2 2 31/05/2017 05:00
.
.
So every entity id has 6 statuses, and every status has an update datetime. Each status has an activity attached to it.
For example 1 - Started journey
2 - Reached first destination
3 - Left Point A, moving towards B. etc
I need to get an output in the below format for specific entity id eg 3 and 4. I need the time for status 3 and 4 independently.
entity_id time_started_journey time_reached_first_destination
(update time of status 3) (update time of status 4)
--------------------------------------------------------------
1 29/05/2017 7:00 29/05/2017 14:00
2 30/05/2017 7:00 30/05/2017 16:00
Later I need to calculate the total time which would be the difference of the two.
How can I achieve the desired result using mysql.
I tried using Union operator but cannot do it separate columns.
Also, tried using case when operator with the below query but failed.
select distinct entityid,
(case status when 3 then freight_update_time else 0 end)
as starttime,
(case status when 4 then freight_update_time else 0 end) as endtime
from table ;
Can anyone throw light on this?
Conditional aggregation is one way to return a resultset that looks like that.
SELECT t.entityid
, MAX(IF(t.status=3,t.updated_date,NULL)) AS time_started_journey
, MAX(IF(t.status-4,t.updated_date,NULL)) AS time_reached_first_destination
FROM mytable t
WHERE t.status IN (3,4)
GROUP BY t.entityid
ORDER BY t.entityid
This is just one suggestion; the specification is unclear about what the query should do with duplicated status values for a given entityid.
There are other query patterns that will return similar results.
My query in MySQL
SELECT
e3.updated_date AS sta3,
e4.updated_date AS sta4
FROM
`prueba` AS e3
LEFT JOIN prueba AS e4
ON
e3.entityId = e4.entityId AND e4.status = 4
WHERE
e3.status = 3
OUTPUT:

last entered value row in group by Mysql

My Query-
SELECT id, MAX(sl), details_sp FROM shareholderreceive GROUP BY id
and result
id MAX(sl) details_sp
1 76
2 74
3 64
4 67
5 69
6 70
10 72
But i need Those MAX(sl) Where details_sp column has last entered value.
My expected table is -
id MAX(sl) details_sp
1 72 Jul'16
2 74
3 64
4 62 Aug'16
5 69
6 70
10 71 Aug'16
here, data type details_sp is Varchar.
What query do I need to get this in MySQL?
What I think you mean is that when there is a details_sp filled in you need the sl value of that row and when there is no details_sp you need the max sl value?
If so, don't use MAX() but use the ORDER BY with the GROUP BY.
SELECT id, sl, details_sp
FROM shareholderreceive
ORDER BY details_sp DESC, sl DESC
GROUP BY id
The only problem with this is that you can never order by a date when it is a varchar value. This means you can never get the latest entry with just a varchar as a date.
So if there is a way, make the details_sp a date value (when you don't have a day just use the first day of the month, so 2017-06-01 for juli 2017) and use DATE_FORMAT() in MySQL or date_format in PHP (or JAVA or etc).

Missing values on count in mysql

I'm just stuck with this issue atm and I'm not 100% sure how to deal with it.
I have a table where I'm aggregating data on week
select week(create_date),count(*)
from user
where create_date > '2015-02-01'
and id_customer between 9 and 17
group by week(create_date);
the results that I'm getting have missing values in the count, as shown below
5 334
6 376
7 394
8 405
9 504
10 569
11 709
12 679
13 802
14 936
15 1081
16 559
21 1
24 9
25 22
26 1
32 3
34 1
35 1
For example here from 16 to 21 there a obviously 4 values missing I would like these values to be included and count to be 0. I want this because I want the weeks to be matching with other metrics as we are outputting them in an excel file for internal analysis.
Any help would be greatly appreciated.
The problem is that an sql query cannot really produce data that is not there at all.
You have 3 options:
If you have data for each week in your entire table for the period you are querying, then you can use a self join to get the missing weeks:
select week(t1.create_date), count(t2.id_customer)
from customer t1
left join customer t2 on t1.id_customer=t2.id_customer and t1.create_date=t2.create_date and t2.id_customer between 9 and 17
where t1.create_date > '2015-02-01'
group by week(t1.create_date)
If you have missing weeks from the customer table as whole, then create a helper table that contain week numbers from 1 or 0 (depending on mysql config) to 53 and do a left join to this helper table.
Use a stored procedure that loops through the results of your original query and inserts the missing data in the resultset using a temporary table and then returns the extended dataset as result.
The problem is that there is no data matching your criteria for the missing weeks. A solution will be to join from a table that has all week numbers. For example if you create a table weeknumbers with one field weeknumber containing all the numbers from 0 to 53 you can use something like this
select weeknumber,count(user.*)
from weeknumbers left join user on (weeknumbers.weeknumber=week(user.create_date)
and user.create_date > '2015-02-01'
and user.id_customer between 9 and 17)
group by weeknumber;
Additionaly you might want to limit the week numbers you do not want to see.
The other way is to do it in the application.