I have table just like this :
p_central_ticket
================
- t_id ======> id ticket
- t_open_by ======> name that raise the ticket
- t_closed_by ======> name that closed the ticket
- t_open_time ======> open ticket time
- t_closed_time ======> closed ticket time
How should i do, if i want to show the Count all tickets that closed by name, and closed time today, weekly, monthly and yearly ? Just like this :
Name today weekly monthly yearly
=================================================================
test1#random.com 2 10 70 1000
test2#random.com 5 14 60 1234
Sample data :
t_id t_open_by t_closed_by t_open_time t_closed_time
===========================================================================
1 amir#random.com test1#random.com 2018-03-28 2018-03-29
2 tiki#random.com test1#random.com 2018-04-28 2018-05-29
Need Help guys...
Thanks
Something like that:
SELECT `t_closed_by`,
COUNT( case when `t_closed_time` > curdate() - interval '1' day THEN 1 END ) as today,
COUNT( case when `t_closed_time` > curdate() - interval '7' day THEN 1 END ) as weekly,
COUNT( case when `t_closed_time` > curdate() - interval '1' month THEN 1 END ) as monthly,
COUNT( case when `t_closed_time` > curdate() - interval '1' year THEN 1 END ) as yearly
FROM Table1
GROUP BY `t_closed_by`
Demo: http://sqlfiddle.com/#!9/3d792/11
Something like the below can be used in MySQL: (Note please check the Syntax if there is any error.)
SELECT a1.t_closed_by as Name,
(SELECT COUNT(*) FROM p_central_ticket WHERE t_closed_time = CURDATE() and t_closed_by = a1.t_closed_by) as today,
(SELECT COUNT(*) FROM p_central_ticket WHERE t_closed_time > DATE_SUB(CURDATE(), INTERVAL 7 DAY) and t_closed_by = a1.t_closed_by) as weekly,
(SELECT COUNT(*) FROM p_central_ticket WHERE t_closed_time > DATE_SUB(CURDATE(), INTERVAL 30 DAY) and t_closed_by = a1.t_closed_by) as monthly,
(SELECT COUNT(*) FROM p_central_ticket WHERE t_closed_time > DATE_SUB(CURDATE(), INTERVAL 365 DAY) and t_closed_by = a1.t_closed_by) as yearly
FROM (SELECT DISTINCT t_closed_by FROM p_central_ticket) a1 ;
You can use this to get records from the tables with even minutes time interval
SELECT column1,column2,.... FROM tableName
WHERE
(DateAndTime BETWEEN '2019-02-11 14:00' AND '2019-02-12 22:00')
AND
(DATEPART(MINUTE, DateAndTime) % 60 = 0)
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 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 have tables that contain same field, for example:
p_central_ticket p_south_ticket p_west_ticket
=====================================================================
- t_id - t_id - t_id
- t_open_by - t_open_by - t_open_by
- t_closed_by - t_closed_by - t_closed_by
- t_open_time - t_open_time - t_open_time
- t_closed_time - t_closed_time - t_closed_time
One thing that i expect is output just like this, but definitely for 3 table above in single query:
Name today weekly monthly yearly
=================================================================
test1#random.com 2 10 70 1000
test2#random.com 5 14 60 1234
But, my query right now just for calculate 1 table.
SELECT t_closed_by As Username, ixt_user_type.user_owner As Role,
COUNT( case when t_closed_time > curdate() - interval 1 day THEN 1 END ) as today,
COUNT( case when t_closed_time > curdate() - interval 7 day THEN 1 END ) as weekly,
COUNT( case when t_closed_time > curdate() - interval 1 month THEN 1 END ) as monthly,
COUNT( case when t_closed_time > curdate() - interval 1 year THEN 1 END ) as yearly
FROM p_central_ticket
LEFT JOIN m_event_type ON p_central_ticket.t_req_type = m_event_type.ev_type
LEFT JOIN ixt_user_type ON m_event_type.ev_user_type_target = ixt_user_type.user_type
WHERE t_status = 9
GROUP BY t_closed_by;
My question is, how should i do, to make my query calculate from 3 tables but in single query ?
You can use UNION to merge three tables and apply all your join on that merged table like below -
SELECT t_closed_by As Username, ixt_user_type.user_owner As Role,
COUNT( case when t_closed_time > curdate() - interval 1 day THEN 1 END ) as today,
COUNT( case when t_closed_time > curdate() - interval 7 day THEN 1 END ) as weekly,
COUNT( case when t_closed_time > curdate() - interval 1 month THEN 1 END ) as monthly,
COUNT( case when t_closed_time > curdate() - interval 1 year THEN 1 END ) as yearly
FROM
( select * from p_central_ticket
union
select * from p_south_ticket
union
select * from p_west_ticket
)A
LEFT JOIN m_event_type ON A.t_req_type = m_event_type.ev_type
LEFT JOIN ixt_user_type ON m_event_type.ev_user_type_target = ixt_user_type.user_type
WHERE t_status = 9
GROUP BY t_closed_by
SELECT COUNT(*) FROM `table` WHERE `datetime` > SUBDATE(NOW(), INTERVAL 1 DAY)
This will get number of entries during last day. But is it possible to get number of entries for multiple intervals without having to send variation of this query multiple times (INTERVAL 1 DAY, INTERVAL 1 WEEK, INTERVAL 1 MONTH, ...)?
You need CASE WHEN expression to accomplish that.
SELECT
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 1 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END) AS lastDay,
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 7 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END ) AS lastSevenDays,
COUNT(*) AS lastThirtyDays
FROM `table`
WHERE
DATE(`datetime`) >= CURDATE() - INTERVAL 30 DAY
How to use CASE WHEN expression
Note: If your requirement is to get result of last day, last 7 days and last 30 days then go with this query.
EDIT:
If you have an index on datetime field then the above query will fail to use that index. Please use the query given below in order to utilize the index on datetime.
SELECT
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 1 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END) AS lastDay,
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 7 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END ) AS lastSevenDays,
COUNT(*) AS lastThirtyDays
FROM `table`
WHERE
`datetime` >= (NOW() - INTERVAL 30 DAY - INTERVAL HOUR(NOW()) HOUR - INTERVAL MINUTE(NOW()) MINUTE - INTERVAL SECOND(NOW()) SECOND)
I need to select all rows in my database that were created last month.
For example, if the current month is January, then I want to return all rows that were created in December, if the month is February, then I want to return all rows that were created in January. I have a date_created column in my database that lists the date created in this format: 2007-06-05 14:50:17.
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
Here's another alternative. Assuming you have an indexed DATE or DATETIME type field, this should use the index as the formatted dates will be type converted before the index is used. You should then see a range query rather than an index query when viewed with EXPLAIN.
SELECT
*
FROM
table
WHERE
date_created >= DATE_FORMAT( CURRENT_DATE - INTERVAL 1 MONTH, '%Y/%m/01' )
AND
date_created < DATE_FORMAT( CURRENT_DATE, '%Y/%m/01' )
If there are no future dates ...
SELECT *
FROM table_name
WHERE date_created > (NOW() - INTERVAL 1 MONTH);
Tested.
Alternatively to hobodave's answer
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
You could achieve the same with EXTRACT, using YEAR_MONTH as unit, thus you wouldn't need the AND, like so:
SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM date_created) = EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL
1 MONTH)
SELECT *
FROM yourtable
where DATE_FORMAT(date_created, '%Y-%m') = date_format(DATE_SUB(curdate(), INTERVAL 1 month),'%Y-%m')
This should return all the records from the previous calendar month, as opposed to the records for the last 30 or 31 days.
Even though the answer for this question has been selected already, however, I believe the simplest query will be
SELECT *
FROM table
WHERE
date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
WHERE created_date >= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH)), INTERVAL 1 DAY)
AND created_date <= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)), INTERVAL 0 DAY)
This worked for me (Selects all records created from last month, regardless of the day you run the query this month)
Alternative with single condition
SELECT * FROM table
WHERE YEAR(date_created) * 12 + MONTH(date_created)
= YEAR(CURRENT_DATE) * 12 + MONTH(CURRENT_DATE) - 1
select fields FROM table
WHERE date_created LIKE concat(LEFT(DATE_SUB(NOW(), interval 1 month),7),'%');
this one will be able to take advantage of an index if your date_created is indexed, because it doesn't apply any transformation function to the field value.
Here is the query to get the records of the last month:
SELECT *
FROM `tablename`
WHERE `datefiled`
BETWEEN DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH )
AND
LAST_DAY( DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH ) )
Regards
- saqib
if you want to get orders from last month, you can try using
WHERE MONTH(order_date) = MONTH(CURRENT_DATE()) -1
One more way to do this in:
MYSQL
select * from <table_name> where date_created >= DATE_ADD(NOW(), INTERVAL -30 DAY);
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)