I have a query that compares this month's numbers to last month and upper month. The only issue is that colleagues complain about the labelling.
I have used M1 = last month and M2 = upper month, but some people still get it mixed up. I want to put in the actual month instead of M1, M2 and so on. Any ideas would help. This is my code
SELECT *,
CONCAT(FORMAT((current_downloads/M_1)*100,2),'%') AS `M_1_Ratio`,
CONCAT(FORMAT((current_downloads/M_2)*100,2),'%') AS `M_2_Ratio`
FROM
(SELECT count(*) AS current_downloads
FROM `purchase`
WHERE date(`purchase`.`timestamp`) >= DATE_FORMAT(NOW() ,'%Y-%m-01')) t1
JOIN
(SELECT count(*) AS M_1
FROM `purchase`
WHERE date(`purchase`.`timestamp`) BETWEEN DATE_SUB(DATE_FORMAT(NOW(),'%Y-%m-01'), INTERVAL 1 MONTH) AND DATE_SUB(DATE(NOW()), INTERVAL 1 MONTH)) t2
JOIN
(SELECT count(*) AS M_2
FROM `purchase`
WHERE date(`purchase`.`timestamp`) BETWEEN DATE_SUB(DATE_FORMAT(NOW(),'%Y-%m-01'), INTERVAL 2 MONTH) AND DATE_SUB(DATE(NOW()), INTERVAL 2 MONTH)) t3
That gives something like this.
I need the header names to be actual months.
This is a horrible hack (and will only work if your output is purely for presentation), but you could just add another line of data to the table which includes the month names by using a UNION:
SELECT DATE_FORMAT(NOW(), '%b %y') as Current_Downloads, DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%b %y') as M_1, DATE_FORMAT(NOW() - INTERVAL 2 MONTH, '%b %y') as M_2, DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%b %y') as M_1_Ratio, DATE_FORMAT(NOW() - INTERVAL 2 MONTH, '%b %y') as M_2_Ratio
UNION ALL
... your query ...
This will give you something that looks like this:
Current Downloads M_1 M_2 M_1_Ratio M_2_Ratio
Mar 18 Feb 18 Jan 18 Feb 18 Jan 18
12,168 12,121 13,345 100.39% 91.18%
Related
I am trying to write a query to get the last 4 weeks (Mon-Sun) of data. I want every week of data to be stored with an individual and shared table.
every week data store based on name if same name repeated on single week amt should sum and if multiple name it should be show data individual, To see an example of what I am looking for, I have included the desired input and output below.
this is my table
date
amt
name
2022-04-29
5
a
2022-04-28
10
b
2022-04-25
11
a
2022-04-23
15
b
2022-04-21
20
b
2022-04-16
20
a
2022-04-11
10
a
2022-04-10
5
b
2022-04-05
5
b
i want output like this
date
sum(amt)
name
2022-04-25 to 2020-04-29
16
a
2022-04-25 to 2020-04-29
10
b
2022-04-18 to 2022-04-24
35
b
2022-04-11 to 2022-04-17
30
a
2022-04-04 to 2022-04-10
10
b
I would appreciate any pointers or 'best-practises' which I should employ to achieve this task.
You can try to use DATE_ADD with WEEKDAY get week first day and end day.
SELECT
CASE WHEN
weekofyear(`date`) = weekofyear(NOW())
THEN 'current week'
ELSE
CONCAT(date_format(DATE_ADD(`date`, interval - WEEKDAY(`date`) day), '%Y-%m-%d'),' to ',date_format(DATE_ADD(DATE_ADD(`date`, interval -WEEKDAY(`date`) day), interval 6 day), '%Y-%m-%d'))
END 'date',
SUM(amt)
FROM T
GROUP BY
CASE WHEN
weekofyear(`date`) = weekofyear(NOW())
THEN 'current week'
ELSE
CONCAT(date_format(DATE_ADD(`date`, interval - WEEKDAY(`date`) day), '%Y-%m-%d'),' to ',date_format(DATE_ADD(DATE_ADD(`date`, interval -WEEKDAY(`date`) day), interval 6 day), '%Y-%m-%d'))
END
sqlfiddle
EDIT
I saw you edit your question, you can just add name in group by
SELECT
CONCAT(date_format(DATE_ADD(`date`, interval - WEEKDAY(`date`) day), '%Y-%m-%d'),' to ',date_format(DATE_ADD(DATE_ADD(`date`, interval -WEEKDAY(`date`) day), interval 6 day), '%Y-%m-%d')) 'date',
SUM(amt),
name
FROM T
GROUP BY
CONCAT(date_format(DATE_ADD(`date`, interval - WEEKDAY(`date`) day), '%Y-%m-%d'),' to ',date_format(DATE_ADD(DATE_ADD(`date`, interval -WEEKDAY(`date`) day), interval 6 day), '%Y-%m-%d')),
name
ORDER BY 1 desc
sqlfiddle
This is in SQL Server, and just a mess about. Hopefully it can be of some help.
with cteWeekStarts
as
(
select
n,dateadd(week,-n,DATEADD(week, DATEDIFF(week, -1, getdate()), -1)) as START_DATE
from
(values (1),(2),(3),(4)) as t(n)
), cteStartDatesAndEndDates
as
(
select *,dateadd(day,-1,lead(c.start_date) over (order by c.n desc)) as END_DATE
from cteWeekStarts as c
)
,cteSalesSumByDate
as
(
select s.SalesDate,sum(s.salesvalue) as sum_amt from
tblSales as s
group by s.SalesDate
)
select c3.n as WeekNum,c3.START_DATE,isnull(c3.END_DATE,
dateadd(day,6,c3.start_date)) as END_DATE,
(select sum(c2.sum_amt) from cteSalesSumByDate as c2 where c2.SalesDate
between c3.START_DATE and c3.END_DATE) as AMT
from cteStartDatesAndEndDates as c3
order by c3.n desc
I have function get day of week and week from current day in mysql
It look like.
select
DATE_FORMAT(now(), '%U') as w,
DATE_FORMAT(now(), '%w') as day_of_w;
It return w is 37 and day_of_week is 1. How to get correct value w is 37 and day_of_week is 1 of previous year.
I using
select
DATE_FORMAT(now() interval 1 year, '%U') as w,
DATE_FORMAT(now() interval 1 year, '%w') as day_of_w;
But SQL cannot execute.
The function to turn a string into a date is STR_TO_DATE. If you want to get the date for week 37, day 1 in 2019, you could use
select str_to_date('37 1 2019', '%U %w %Y')
If you want the date for today's week and day number in last year:
select str_to_date(concat_ws(' ', date_format(current_date, '%U'),
date_format(current_date, '%w'),
year(current_date) - 1),
'%U %w %Y')
Be aware though, that some years have a week 53 while others don't. If you run this query in a year's 53rd week, you don't get a valid result.
select DAYOFWEEK(now()) day_of_week, week(now()) week from dual
your query has syntactical problem. you forgot +/- symbol
select DATE_FORMAT(now() + interval 1 year, '%U') as w
,DATE_FORMAT(now() + interval 1 year, '%w') as day_of_w;
You just need to use DATE_ADD function in MYSQL to change the date to last year.
select DATE_FORMAT(DATE_ADD(now(), INTERVAL -1 YEAR), '%U') as w
,DATE_FORMAT(DATE_ADD(now(), INTERVAL -1 YEAR), '%w') as day_of_w;
Result:
36 6
Current and last year date:
select now() as curr_yr_date, DATE_ADD(now(), INTERVAL -1 YEAR) as last_yr_date;
Result:
2020-09-14 07:13:24 2019-09-14 07:13:24
I have very little knowledge of MYSQL so please forgive me. I have a wordpress form using Formidable Forms. I am querying the database to find forms that were logged from the beginning of this month to the current date which is....
SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) < now() and date(created_at) > last_day(curdate() - interval 1 month) and field_id=30
field_id=30 is the date field. This procedure works.
I also have a similar procedure for last month which gives me the forms created from the beginning of last month to the same date of last month so if today is 14/08. The procedure would display a count of all forms from 01/07-14/07 which it does...
SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) < NOW () - interval 1 month and date(created_at) > last_day(curdate() - interval 2 month) and field_id=30;
I need to try to join these so they output the data in the same query. Is this possible? I've tried union and join and everything tells me I have an error in my code. The error that comes up is cannot calculate position of the second select.
I would also like it to calculate the number of days left in the current month and I will be adding another procedure to give me the total forms created last month so I can run formulas on them.
So the table will look like...
Month Tickets
08 60
07 89
Total LM 194
Diff 134
Days Left 17
Target 7.8
Apologies for the long question and I appreciate any help.
Thanks
So I have the right data now but I need to change the order it appears. My query is...
(SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) < now() and date(created_at) > last_day(curdate() - interval 1 month) and field_id=30)
UNION
(SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) < NOW () - interval 1 month and date(created_at) > last_day(curdate() - interval 2 month) and field_id=30)
UNION
(SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) <= last_day(now() - interval 1 month) and date(created_at) > last_day(now() - interval 2 month) and field_id=30)
UNION
(SELECT DAYOFMONTH(now()) as D1, DAY(LAST_DAY(now())) as DaysInMonth);
This gives me the table...
Month.....Tickets
8.....62
7.....84
7.....194
14....31
The first row is the forms created this month. 84 is the forms created to the same date last month. 194 is the total for last month and the last row is the day of the month and the total days in the month.
I need to change the format slighly so I can do calculations on the results.
I need...
ThisMth.....LastMth.....LastMthTotal
62..........84..........194
14..........31
Thanks
UNION is the correct answer, if you want both as rows
But you need to enter around both SELECTS parenthesis
(SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) < now() and date(created_at) > last_day(curdate() - interval 1 month) and field_id=30)
UNION
(SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) < NOW () - interval 1 month and date(created_at) > last_day(curdate() - interval 2 month) and field_id=30);
for that you can use
(SELECT (SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) < now() and date(created_at) > last_day(curdate() - interval 1 month) and field_id=30) ThisMth
,
(SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) < NOW () - interval 1 month and date(created_at) > last_day(curdate() - interval 2 month) and field_id=30) LastMth
,
(SELECT month(created_at) as Month, count(id) as Tickets
FROM wp_frm_item_metas
WHERE date(created_at) <= last_day(now() - interval 1 month) and date(created_at) > last_day(now() - interval 2 month) and field_id=30) LastMthTotal)
UNION
(SELECT DAYOFMONTH(now()) as D1, DAY(LAST_DAY(now())) as DaysInMonth,'');
I am trying to count how many hours of the day there is data in the database.
I use this query:
SELECT
HOUR(date) AS `hour`, COUNT(date)
FROM fb_posts
WHERE DATE(date) = CURDATE() - INTERVAL 1 DAY
GROUP BY hour
I got the query from here
example:
hour COUNT(date)
00 55
01 2
02 33
Now I want calculate how many hours there was data?
Above example should output value 3, because there was data at hour 00, 01 and 02
something would like to add COUNT(hour)like this:
SELECT
HOUR(date) AS `hour`, COUNT(date)**,COUNT(hour)**
FROM fb_posts
WHERE DATE(date) = CURDATE() - INTERVAL 1 DAY
GROUP BY hour
select count(*)
from
(
SELECT HOUR(date) AS hour
FROM fb_posts
WHERE DATE(date) = CURDATE() - INTERVAL 1 DAY
GROUP BY hour
) tmp
you are looking for count(distinct column) https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_count-distinct
SELECT count(distinct HOUR(date)) AS distinct_hour_count
FROM fb_posts
WHERE DATE(date) = CURDATE() - INTERVAL 1 DAY
I'm trying to get all posts from the 12 last month, group by month. I have a quite correct query:
SELECT MONTH(time) as mois, YEAR(time) as annee, count(*) as nbre
FROM touist_stories
WHERE time >= DATE_SUB(now() + INTERVAL 1 MONTH, INTERVAL 2 YEAR)
group by MONTH(time)
order by YEAR(time) DESC, MONTH(time) DESC
But one month is always missing : november 2012
I tryied to add
+ INTERVAL 1 MONTH
to now() but it still missing... How can I get the 12 last month and not the 11 ones please?
Thanks
To get one year ago, here's a technique I've used in the past. Using #mysql variables, create a date based on the first day of a given month/year (via now()), then subtract 12 months. This example will get from Oct 1, 2012 to current -- which will include current Oct 2013. To exclude that, just add to where clause where I re-added 1 year so it goes from Oct 1, 2012 at 12:00:00 am to LESS THEN Oct 1, 2013 12:00:00.
SELECT
MONTH(time) as mois,
YEAR(time) as annee,
count(*) as nbre
FROM
touist_stories,
( select #lastYear := date_add( DATE_FORMAT(NOW(),
'%Y-%m-01'), interval -11 month) ) sqlvar
WHERE
time >= #lastYear
group by
MONTH(time)
order by
YEAR(time) DESC,
MONTH(time) DESC
Revised to make it go 11 months back (to November per example), and include UP TO AND INCLUDING all Current October activity.
For realy want on year data use 11 MONTH not 12
SELECT time
FROM touist_stories
WHERE time
BETWEEN
date_sub(Now(), INTERVAL 11 MONTH)
AND
Now();