MySQL get dates for drawing barchart - mysql

I'm trying to pull all information inside a given date range from my database using something like this query:
SELECT transactionDate, SUM(transactionTotal)
FROM transaction
WHERE transactionDate BETWEEN '2014-06-01' AND '2014-08-11'
AND transactionType = 'end'
GROUP BY DAYOFMONTH(transactionDate)
ORDER BY transactionDate ASC
But somehow I only get the data for 1 month
2014-06-01 20:38:05 4811500.00
2014-06-02 20:42:59 5924950.00
2014-06-03 20:44:38 3811500.00
2014-06-04 11:45:13 4472000.00
2014-06-05 15:34:53 7922000.00
2014-06-06 17:45:28 5027000.00
2014-06-07 11:25:38 4378000.00
2014-06-08 07:59:04 4250000.00
2014-06-09 08:41:49 4766500.00
2014-06-10 01:23:35 4071000.00
2014-06-11 01:01:30 1459000.00
2014-06-12 15:05:08 2960000.00
2014-06-13 00:47:09 1160000.00
2014-06-14 16:52:20 4208000.00
2014-06-16 00:05:18 3947500.00
2014-06-17 00:18:39 4926000.00
2014-06-18 00:33:38 4244500.00
2014-06-19 00:43:39 4045000.00
2014-06-20 22:47:54 2649500.00
2014-06-21 23:06:04 4030000.00
2014-06-22 23:19:22 945500.00
2014-06-23 23:29:27 3015000.00
2014-06-24 23:35:56 2420000.00
2014-06-25 00:02:03 3920000.00
2014-06-26 00:50:33 4841000.00
2014-06-27 10:39:14 4095000.00
2014-06-28 07:43:06 5605500.00
2014-06-29 11:48:24 1939000.00
2014-06-30 10:49:50 3620000.00
As you can see, I get the results from 2014-06-01 to 2014-06-01 even when all other dates also have data to display.
Hope you can help me, thanks!

You're misusing GROUP BY and the pernicious MySQL GROUP BY extension is biting you. You're grouping your data into 31 buckets with your GROUP BY DAYOFMONTH() , so there's no way you'll get more than 31 rows in your result set. You're then (misusing the extension) displaying some arbitrarily selected transaction_date value from each of your 31 groupings. It happens to be a June date, and this has tricked you into thinking you've only selected June records. You've actually selected all the dates in your range, but mistakenly grouped July and August records with your June records. Ouch.
Second, using BETWEEN to select date ranges from a DATETIME column isn't quite right, because it gets the end of the range wrong. BETWEEN '2014-06-01' AND '2014-08-11' gets the items dated from the first of June up until the very first moment of August 11th. So something happening at noon on August 11th won't get selected.
Here is the query you need to do this job correctly.
SELECT DATE(transactionDate),
SUM(transactionTotal)
FROM transaction
WHERE transactionDate >= '2014-06-01'
AND transactionDate < '2014-08-11' + INTERVAL 1 DAY
AND transactionType = 'end'
GROUP BY DATE(transactionDate)
ORDER BY DATE(transactionDate) ASC
What's going on here? First, we're grouping by just the date of each transaction, using DATE(), and we're including that grouped value in our result set with SELECT DATE().
Second, the date range selection takes everything on or after midnight on June first, up until the moment right before midnight on August 12th. That's the point of transactionDate < '2014-08-11' + INTERVAL 1 DAY. It takes the whole day's worth of items for August 11.
There's a writeup of this corner of SQL tech here: http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/

Use the following sql query to get desired results
SELECT transactionDate, SUM(transactionTotal) FROM transaction WHERE transactionDate BETWEEN '2014-06-01' AND '2014-08-11' AND transactionType = 'end' GROUP BY CAST(transactionDate AS DATE) ORDER BY transactionDate ASC

Related

grouping data in SQL based on date manipulations

I've sample data here (date: yyyy-mm-dd format)
Headquarter date Sales monthyear
1 2020-10-30 1000 202010
1 2020-10-31 500 202010
1 2020-11-01 1000 202011
1 2020-11-02 2000 202011
1 2020-11-03 3000 202011
1 2020-11-04 1000 202011
1 2020-11-05 1000 202011
I have to sum all the sales values from 2nd of current month to 2nd of next month. Grouping by headquarter and monthyear. So if I run the query, based on current_date(), the sales value should be added to that month respectively.
To brief my explanation, here's the desired result
headquarter sales monthyear
1 4500 202010
1 5000 202011
So here 30th, 31st of Oct and 1st, 2nd of Nov falls in my condition and their values are summed to oct month. But 3rd, 4th of Nov values are summed to Nov month. Likewise it happens with every month.
If I run the sql query, as today is 1st Nov (IST), today's value should be added to previous month.
I'm looking for some help in making the SQL query here.
GROUP BY DATE_FORMAT(`date` - INTERVAL 1 DAY, '%y%m')
MySQL offers the year_month specifier for extract(). I assume you want everything from the 2nd of one month to the first of the next month. If so, subtract one day:
select headquarter,
extract(year_month from date - interval 1 day) as yyyymm,
sum(sales)
from sample
group by headquarter, yyyymm;

How to get the number of active events happening in a week given start and end date (MYSQL)?

This is the current table I have.
ID Start_Date End_Date
6446 2018-01-01 00:00:00 2018-04-01 00:00:00
6848 2018-05-01 00:00:00 2018-05-31 00:00:00
3269 2016-11-09 00:00:00 2016-11-21 00:00:00
7900 2018-11-07 00:00:00 2018-11-30 00:00:00
4006 2017-04-06 00:00:00 2017-04-30 00:00:00
Is there a way to get the number of active events per week? Some events might run past a few weeks. Event ID is distinct and can be used to count.
Please help and happy to furnish more info if required.
EDIT 1: The dataset I want is
2019 week 1 - 60 active events
2019 week 2 - 109 active events
I know about WEEK(datetime), however that does not capture the event being active for subsequent weeks.
The issue is that I don't capture the number of active events after the week they are started.
EDIT 2: Week would be defined as the integer returned using the week() function in mysql on a date object. My data is only for 2019.
Try to use count() function in MySQL.
SELECT COUNT(*) FROM your_table WHERE Start > 'start-date' AND End < 'end-date'
Give a try to below query
SELECT
IFNULL(DATE_FORMAT(Start_Date, '%Y WEEK %U'), 0) AS STARTDate,
IFNULL(DATE_FORMAT(End_Date, '%Y WEEK %U'), 0) AS ENDDate,
IFNULL(COUNT(ID),0) AS total,
group_concat(ID)
FROM `event`
where Start_Date < End_Date
Group by STARTDate;
I found an answer, but encountered a new problem.
Building upon Kranti's code, the answer is as follows.
SELECT
EXTRACT(WEEK FROM starting_date) AS STARTDate,
EXTRACT(WEEK FROM ending_date) AS ENDDate,
discount_type,
COUNT(ID) AS total
FROM `event`
where starting_date < ending_date
Group by 1,2
What this gives me is the number of events that have happened from Week 1 - 3, Week 1-4 etc, so on and so forth.
Afterwards, we do a left join with the weeks of interest, on the condition where the week numbers are in between STARTDate and ENDDate. Due to how a left join works, it will duplicate rows for all the rows that fulfill the specific condition.
We follow up with a groupby and sum, which will give us the number of events that were active, for each week.

MySQL order by dayname (custom formatted)

The SQL I'm using on MySQL database is
SELECT
CONCAT(YEAR(EVE_DATE),'-',MONTH(EVE_DATE),'-',DAYNAME(EVE_DATE)) AS WEEKDAY_DATE,
SUM(EVE_OCCUR)
FROM
TABLE
WHERE
EVE_DATE BETWEEN '2015-01-01' AND '2015-10-31'
GROUP BY
WEEKDAY_DATE
ORDER BY WEEKDAY_DATE
The output of the weekname it generates is in the format "YYYY-MON-DAY". Currently, the output is not ordered. I would like to order it as below
2015-01-Sun
2015-01-Mon
2015-01-Tue
2015-01-Wed
2015-01-Thu
2015-01-Fri
2015-01-Sat
2025-02-Sun
2015-02-Mon
2015-02-Tue
2015-02-Wed
2015-02-Thu
2015-02-Fri
2015-02-Sat
and so on
Could someone please help me?
You can order by EVE_DATE:
SELECT
CONCAT(YEAR(EVE_DATE),'-',MONTH(EVE_DATE),'-',DAYNAME(EVE_DATE)) AS WEEKDAY_DATE,
SUM(EVE_OCCUR)
FROM TABLE
WHERE EVE_DATE BETWEEN '2015-01-01' AND '2015-10-31'
GROUP BY WEEKDAY_DATE
ORDER BY EVE_DATE
SqlFiddleDemo
EDIT:
Example what I wanted to communicate in comment:
2015-01-01 - Thursday -- 4th
2015-01-02 - Friday -- 5th
2015-01-03 - Saturday -- 6th
2015-01-04 - Sunday -- 7th
2015-01-05 - Monay -- should it be the first
2015-01-06 - Tuesday -- 2nd
2015-01-07 - Wednesday -- 3rd
2015-01-08 - Thurday
2015-01-09 - Friday
2015-01-10 - Saturday
2015-01-11 - Sunday
2015-01-12 - Monday -- 8th
When you sort by date you sort by actual date and not its textual representation.
Now you want to start from Monady but Monday does not exists in this year/month as starting point. Do you want to shuffle Monady? What you propose is nonsense for me.
Why are you using that concat() statement when MySQL has date_format()?
SELECT DATE_FORMAT(eve_date, '%Y-%m-%a') as weekday_date,
SUM(EVE_OCCUR)
FROM TABLE
WHERE eve_date >= '2015-01-01' AND eve_date < '2015-02-01'
GROUP BY WEEKDAY_DATE
ORDER BY MIN(eve_date);
For the ORDER BY, I would recommend using an aggregation function, rather than ORDER BY eve_date. This is consistent with how standard SQL works.
I also changed the date comparisons to use >= and <. BETWEEN is a dangerous habit with dates, because it works differently when there is a time component. The above method works equally well for dates and date/times.
You can use EVE_DATE column to sort the output in Query
SELECT
CONCAT(YEAR(EVE_DATE),'-',MONTH(EVE_DATE),'-',DAYNAME(EVE_DATE)) AS WEEKDAY_DATE,
SUM(EVE_OCCUR)
FROM
TABLE
WHERE
EVE_DATE BETWEEN '2015-01-01' AND '2015-10-31'
GROUP BY
WEEKDAY_DATE
ORDER BY YEAR(EVE_DATE),MONTH(EVE_DATE) ,FIELD(DAYNAME(EVE_DATE), 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY');

Get peak amount of active rows from all time

I have the following problem. I have a mysql table that has a startdate and and enddate. Each row is considered active between those dates. Some rows are no longer active, but have been active in the past. For example the following table:
id start end
1 2014-11-11 00:00:00 2015-01-31 23:59:59
2 2014-09-25 10:16:14 2015-06-01 23:59:59
3 2013-12-24 00:00:00 2014-12-01 23:59:59
4 2014-08-13 00:00:00 2016-01-31 23:59:59
5 2013-09-11 00:00:00 2014-09-10 23:59:59
My actual table has way more data than that. Now I need to know what the peak amount of concurrent active rows is without knowing when that peak actually occured. How would I do this in SQL? In the example 4 rows are active at the same time (1-4, not 5) in the time between 2014-11-11 and 2015-01-31 23:59:59. The actual peak time doesn't matter to me as much as the peak amount itself.
Thanks for your help
Find different timestamps of interrest using UNION ALL, count number of active tasks at these timestamps:
select ts, (select count(*) from tablename t2
where timestamps.ts between t2.start and t2.end) as count
from (select start as ts
from tablename
union all
select end
from tablename) as timestamps
order by count desc
limit 1
Finally order descending and pick the highest value only!
(From a non MySQL user, so some details may be wrong... Please comment if that's the case and I'll edit!)

Access 2007 query to capture records that encompass 2 dates

I'm working on a query to get records based on two dates, start and end dates.
What I need to obtain are records that are span some or all of the given period, in other words the start date maybe before the parameter date but less than the end date or start after the start date and end after the end date.
I.e. Start date = 01 Oct 12 and end date 31 Oct 12. I would like to capture records where start date is before 1 Oct but spans this period whether it finishes in November or mid October. As well as records that are between 01 Oct 12 and 31 Oct 12.
In reality I need the records that exclude this period, but first need to make sure I'm getting this dataset correct.
I'm starting with this simple data set stored in MyTable, with both start_date and end_date as Date/Time data type.
id start_date end_date
1 9/29/2012 9/30/2012
2 9/29/2012 10/2/2012
3 9/29/2012 11/1/2012
4 10/2/2012 11/1/2012
5 11/1/2012 11/2/2012
Running the query below, and supplying 2012-10-01 and 2012-10-31 for the range_start and range_end parameters, gives me this output result set.
id start_date end_date
2 9/29/2012 10/2/2012
3 9/29/2012 11/1/2012
4 10/2/2012 11/1/2012
If this is not similar to what you wanted, please edit your question to show us a brief sample set of input data and the output you want from that sample.
Also, note the time components of my start_date and end_date values were all midnight. If your counterparts include any other times of day, you will need to revise the query to deal with them.
This is the SQL from the query I used:
PARAMETERS range_start DateTime, range_end DateTime;
SELECT m.id, m.start_date, m.end_date
FROM MyTable AS m
WHERE
m.start_date Between [range_start] And [range_end]
OR m.end_date Between [range_start] And [range_end]
OR (m.start_date<[range_start] AND m.end_date>[range_end]);