SQL - How to order by min date - mysql

I have a table with logs
PERSON ID LOGDATE (DATETIME)
1000 2015-10-20 10:00:00
1000 2015-11-11 09:10:22
2001 2015-10-11 10:22:11
I need to order the data by LOGDATE -DATETIME - but with only the lowest date for each ID.
select PERSONALID, LOGDATE from TABLE group by PERSONALID order by
MIN(LOGDATE) DESC
I can GROUP by ID - ORDER BY Min DATE (each result by ID), but THE FINAL RESULT doesnt order the results by MIN DATE..
RESULT:
1000 ------------- 2015-10-20 10:00:00 (min date for ID=1000)
2001 ------------- 2015-10-11 10:22:11 (min date for ID=2001)
the right answer is:
RESULT:
2001 ------------- 2015-10-11 10:22:11 (min date for ID=2001)
1000 ------------- 2015-10-20 10:00:00 (min date for ID=1000)
what is wrong?

This should do it:
select PERSONALID, MIN(LOGDATE) as mindate
from TABLE
group by PERSONALID
order by mindate

You need to select MIN(LOGDATE), not LOGDATE. Selecting LOGDATE causes MySQL to return the value of an indeterminate record from within each group—see MySQL Handling of GROUP BY for more information.

Related

Add the continuous date period records into one record with sql

Original Data:
ID Date Original_col
A 2021-04-10 1
B 2021-03-01 1
B 2021-05-01 1
C 2021-03-01 1
C 2021-03-02 2
C 2021-03-03 3
C 2021-05-07 1
Result data:
ID Date Result_col
A 2021-04-10 1
B 2021-03-01 1
B 2021-05-01 1
C 2021-03-01 3
C 2021-05-07 1
For ID = 'C' records, records with date between '2021-03-01' to '2021-03-03' are grouped together, only start date '2021-03-01' and max day '3' is kept, record with date = '2021-05-07' is kept cause there are no bigger records.
There are no strict restrictions on 'the date period', I need to group them together if they are continuous on Original_col.
You can identify the periods by subtracting an enumerated value. This is constant for "adjacent" days. The rest is just aggregation:
select id, min(date), max(original_col) as result_col
from (select t.*,
row_number() over (partition by id order by date) as seqnum
from t
) t
group by id, (date - interval seqnum day);
If the original_column is really enumerating the adjacent dates, then you don't even need a subquery:
select id, min(date), max(original_col) as result_col
from t
group by id, (date - interval original_col day);
However, I don't know if the values are just coincidences in the sample data in the question.

Mysql select query for selecting row by time period

I have a table employee where i want to select a row based on dates.
emp_id validation_user entry_date
-------------------------------------------------------
10 mark 2014-05-01 11:11:00
10 ann 2014-05-01 10:14:00
10 marco 2014-05-01 11:07:00
10 mark 2014-05-01 10:00:00
I would like to have the row when emp_id=10 and entry_date is less than 2014-05-01 11:11:00
This should return me only one row which is closest to 2014-05-01 11:11:00 not three rows
emp_id validation_user entry_date
-------------------------------------------------------
10 marco 2014-05-01 11:07:00
my select statement returns me 3 rows:
SELECT *
FROM emp
where entry_date < "2014-05-01 11:11:00"
Since there is no row_number in MySQL, you can achieve this with limit and order by :
SELECT *
FROM emp
where entry_date < "2014-05-01 11:11:00"
order by entry_date desc
limit 1
What we do here is order by entry_date to make sure the first row is really the first one we want, then we specify to limit the query to 1 value.
We specify to order in descending order as we want the highest value that is lower then the specified date.

mysql get the sum of unique date

From MySQL table I have the list amount based on the dates. I need to get the sum of amount for each date:
ex:
id type date amount
1 1 2015-01-01 100
2 1 2015-01-01 150
3 1 2015-01-02 10
4 1 2015-01-03 250
Here 2015-01-01 appears more than once.
so i need the result like
date amount
2015-01-01 200
2015-01-02 10
2015-01-03 250
My Query getting between this week start and end
SELECT * from mytable WHERE YEARWEEK(`date`) = YEARWEEK(CURRENT_DATE) AND `type` = 1 ORDER BY `date` ASC
You need a group by clause:
SELECT `date`, SUM(amount)
FROM mytable
GROUP BY `date`
I think the result should be
date amount
2015-01-01 250
2015-01-02 10
2015-01-03 250
you can use this mysql query to get that result:
Select date, sum(amount) as amount
from mytable
GROUP BY date
ORDER BY date asc
dont forget to add "ORDER BY" clause if you want the result in good order
Use GROUP BY
Use AS clause to change the column Name
SELECT `date`, SUM(amount) AS amount
FROM mytable
GROUP BY `date`

Given a table with time periods, query for a list of sum per day

Let's say I have a table that says how many items of something are valid between two dates.
Additionally, there may be multiple such periods.
For example, given a table:
itemtype | count | start | end
A | 10 | 2014-01-01 | 2014-01-10
A | 10 | 2014-01-05 | 2014-01-08
This means that there are 10 items of type A valid 2014-01-01 - 2014-01-10 and additionally, there are 10 valid 2014-01-05 - 2014-01-08.
So for example, the sum of valid items at 2014-01-06 are 20.
How can I query the table to get the sum per day? I would like a result such as
2014-01-01 10
2014-01-02 10
2014-01-03 10
2014-01-04 10
2014-01-05 20
2014-01-06 20
2014-01-07 20
2014-01-08 20
2014-01-09 10
2014-01-10 10
Can this be done with SQL? Either Oracle or MySQL would be fine
The basic syntax you are looking for is as follows:
For my example below I've defined a new table called DateTimePeriods which has a column for StartDate and EndDate both of which are DATE columns.
SELECT
SUM(NumericColumnName)
, DateTimePeriods.StartDate
, DateTimePeriods.EndDate
FROM
TableName
INNER JOIN DateTimePeriods ON TableName.dateColumnName BETWEEN DateTimePeriods.StartDate and DateTimePeriods.EndDate
GROUP BY
DateTimePeriods.StartDate
, DateTimePeriods.EndDate
Obviously the above code won't work on your database but should give you a reasonable place to start. You should look into GROUP BY and Aggregate Functions. I'm also not certain of how universal BETWEEN is for each database type, but you could do it using other comparisons such as <= and >=.
There are several ways to go about this. First, you need a list of dense dates to query. Using a row generator statement can provide that:
select date '2014-01-01' + level -1 d
from dual
connect by level <= 15;
Then for each date, select the sum of inventory:
with
sample_data as
(select 'A' itemtype, 10 item_count, date '2014-01-01' start_date, date '2014-01-10' end_date from dual union all
select 'A', 10, date '2014-01-05', date '2014-01-08' from dual),
periods as (select date '2014-01-01' + level -1 d from dual connect by level <= 15)
select
periods.d,
(select sum(item_count) from sample_data where periods.d between start_date and end_date) available
from periods
where periods.d = date '2014-01-06';
You would need to dynamically set the number of date rows to generate.
If you only needed a single row, then a query like this would work:
with
sample_data as
(select 'A' itemtype, 10 item_count, date '2014-01-01' start_date, date '2014-01-10' end_date from dual union all
select 'A', 10, date '2014-01-05', date '2014-01-08' from dual)
select sum(item_count)
from sample_data
where date '2014-01-06' between start_date and end_date;

SQL to return record counts in X intervals

I have a table like this:
id | created_on
1 2013-09-03 20:05:09
2 2013-09-05 17:03:13
...
How do I write a query to return a result of record counts that was created from Date X to Date Y in 7-day intervals?
So the result would look like this:
count | created_on
4 2013-09-17 00:00:00
2 2013-09-24 00:00:00
1 2013-09-31 00:00:00
10 2013-10-07 00:00:00
...
You can go to the beginning of the week by subtracting the day of the week. Here is one way to do that:
select date(created_on - interval dayofweek(created_on) day), count(*)
from t
group by date(created_on - interval dayofweek(created_on) day);
If this is not the day you want the week to start, then you can add an offset day.
Group by the date field, floored to the week:
SELECT
count(*),
YEARWEEK(created_on) as week
FROM
yourtable
GROUP BY week
This assumes that created_on is a type that can be interpreted as a date:
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_yearweek
This will get you weekly groupings, but you may want to then convert that field (which will look like YYYYWW) back to something more readable.
You can try this
SELECT created_on, count( id ) AS count
FROM `test_table`
WHERE created_on
BETWEEN '2013-09-01'
AND '2013-10-10'
GROUP BY WEEK( created_on )