Count of records for the last and current month unix timestamp - mysql

I need to make statistics page for billing with auto query. For example now is july and query must show count of record for the june and current count of records on current day(only july). Sort of:
"records for the last month - 85, for the current day - 32"
I have table customer and row create_time but it is in unix timestamp. Tried
SELECT COUNT(*) FROM customer WHERE create_time >=
UNIX_TIMESTAMP(DATE_SUB(now(), INTERVAL 1 MONTH))
but its absolutely not what i want.
I would appreciate for any help.

Try this:
SELECT *
FROM ( SELECT COUNT(*) AS total_previous_month
FROM customer
WHERE create_time >= concat(date_format(LAST_DAY(now() - interval 1 month),'%Y-%m-'),'01')
AND create_time < LAST_DAY(now() - interval 1 month )
) AS s1,
( SELECT COUNT(*) AS total_previous_month
FROM customer
WHERE create_time >= concat(extract(year from now()),'-',extract(month from now()),'-01')
AND create_time <= now()
) AS s2

You can do this by adding condition to the WHERE:
create_time >= UNIX_TIMESTAMP(DATE_SUB(CURDATE(), INTERVAL 1 month))
in PHP you can calculate the one month back date
$newDate = strtotime('-1 month');
and use this in query

Related

MySQL Rolling Value - subquery with joined value

I am trying to do a single query over a period of a month. This is a working query:
SELECT AVG(days)
FROM (SELECT datediff(IF(MIN(date_end) = '0000-00-00', DATE(NOW()), MAX(date_end)), MIN(date_start)) AS days
FROM tenancies
WHERE deleted_at IS NULL AND date_start < DATE_SUB(NOW(), INTERVAL 1 MONTH)
GROUP BY tenancies.tenant_id)
I want to replace NOW() with a date.
I have another query:
SELECT calendar_date
FROM calendar_dates
WHERE calendar_date BETWEEN NOW() - INTERVAL 1 MONTH AND NOW()
This gets me all the dates I want. If I try to do a double-subquery it doesn't recognize the calendar_date:
SELECT calendar_date, (SELECT AVG(days)
FROM (SELECT datediff(IF(MIN(date_end) = '0000-00-00', DATE(calendar_date), MAX(date_end)), MIN(date_start)) AS days
FROM tenancies
WHERE deleted_at IS NULL AND date_start < DATE_SUB(calendar_date, INTERVAL 1 MONTH)
GROUP BY tenancies.tenant_id) d) AS days
FROM calendar_dates
WHERE calendar_date BETWEEN NOW() - INTERVAL 1 MONTH AND NOW()
Anyone have any suggestions?
I assume it does not recognize DATE(calendar_date) and DATE_SUB(calendar_date, INTERVAL 1 MONTH), If right, Your tenancies table should have a calendar_date field in itself, otherwise you need to join tenancies with calendar_dates table in the middle query too. Because thats a separate query.

sql query to show records created this month

I want to write an sql query that must show me records that are only created last month..for example, if this month is June, I want the query to show me records of May.
This is my query but it is not working.
SELECT COUNT(*) AS stdtotal_today FROM `login`
WHERE `login_account_type` = 'STUDENT'
AND `account_created_date` = CURDATE() - 30
Note that login is the table name and account_created_date is the column name of type date.
Try This :
SELECT * FROM `login`
WHERE `login_account_type` = 'STUDENT' AND YEAR(`account_created_date`) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(`account_created_date`) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
Try this...
SELECT COUNT(*) AS stdtotal_today FROM `login` WHERE account_created_date
BETWEEN DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%Y-%m-01 00:00:00') AND DATE_FORMAT(LAST_DAY(NOW() - INTERVAL 1 MONTH), '%Y-%m-%d 23:59:59')

mysql arithmetik operation (subtraction) last - first of the day(week, month)

i got a MySQL tbl, with some colums, where every 5 min. a new row is inserted with 3 values
1. Auto inc. curent Date Unix timestamp --> date
2. power consumption absolut --> wert01
3. Power Generation absolut --> wert02
To Show this Information in a Graph, for Exampl for weekly power consumption, i need to select the First and the last, which allready Works, but then have to Substract the last from the First and Show only tue result & the day of the werk.
SELECT
(SELECT wert01
FROM sml_splitt
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate()) DAY
ORDER BY date DESC LIMIT 1) AS 'last',
(SELECT wert01
FROM sml_splitt
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate()) DAY
ORDER BY date LIMIT 1) AS 'lirst
I am searching for some days to find a solution, but with no success.
Hopfuly, you could help me.
If you're happy with your query, then you can do the math by nesting it one more time like this: http://sqlfiddle.com/#!9/515ef/1
select t1.last, t1.first, t1.last - t1.first as result
from (
select (
select wert01
from sml_splitt
where dt >= curdate() - interval dayofweek(curdate()) + 6 day
and dt < curdate() - interval dayofweek(curdate()) day
order by dt desc limit 1
) as 'last',
(
select wert01
from sml_splitt
where dt >= curdate() - interval dayofweek(curdate()) + 6 day
and dt < curdate() - interval dayofweek(curdate()) day
order by dt limit 1
) as 'first'
) t1
;
If you really want to work with this data by week for reporting purposes, let me suggest a couple of views. The first will give you all of your distinct beginning of week dates:
create view v1 as
select date(dt) as week_begins
from sml_splitt
where dayofweek(dt) = 1
group by week_begins
The second view joins the first view with itself to give you a week beginning and week ending range:
create view v2 as
select t1.week_begins, coalesce(t2.week_begins,now()) as week_ends
from v1 t1
left join v1 t2
on t2.week_begins = t1.week_begins + interval 7 day
You can see the results here: http://sqlfiddle.com/#!9/a4d1b3/2. Notice that I'm using now() to get the current date and time if the week hasn't ended yet.
From there you can join your view with your original table and use min() and max() function with grouping to get the starting and ending 'wert' values and do any calculations on them that you like.
Here's an example: http://sqlfiddle.com/#!9/a4d1b3/6
select week_begins, week_ends,
min(wert01) as start_wert01,
max(wert01) as end_wert01,
max(wert01) - min(wert01) as power_consumed,
min(wert02) as start_wert02,
max(wert02) as end_wert02,
max(wert02) - min(wert02) as power_generated,
(max(wert02) - min(wert02)) - (max(wert01) - min(wert01)) as net_generated
from v2
inner join sml_splitt
on sml_splitt.dt >= v2.week_begins
and sml_splitt.dt < v2.week_ends
group by week_begins
I hope that helps.

MYSQL SELECT QUERY show all dates between, even if data not present with count=0

Below is the query i have written to fetch the order count with status=1 for last week.
SELECT count(*) as order_count,
DATE_FORMAT(order_date,'%d-%b-%Y') as order_date,
status
FROM customer_order
WHERE date(order_date) >= curdate()
- INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date(order_date) < curdate()
- INTERVAL DAYOFWEEK(curdate())-1 DAY
AND status=1
GROUP BY DATE_FORMAT(order_date, '%Y%m%d'),
status
I am getting result only for the dates present in the table. I need all the dates with count = 0 if data is not present for particular date.
You could try:
SELECT DATE_FORMAT(c1.order_date,'%d-%b-%Y') AS order_date
FROM customer_order AS c1
WHERE DATE_FORMAT(c1.order_date,'%d-%b-%Y')
IN ( SELECT DATE_FORMAT(c2.order_date,'%d-%b-%Y') as order_date2
FROM customer_order AS c2
WHERE date(DATE_FORMAT(c2.order_date,'%d-%b-%Y')) >= curdate()
- INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date(DATE_FORMAT(c2.order_date,'%d-%b-%Y')) < curdate()
- INTERVAL DAYOFWEEK(curdate())-1 DAY
AND c2.status=1
GROUP BY DATE_FORMAT(DATE_FORMAT(c2.order_date,'%d-%b-%Y'), '%Y%m%d'),
c2.status
HAVING count(*)=0
)

MySQL: search orders made since yesterday 3pm till today 4pm

I have table ORDERS where is stored data about orders with their status and the date of order. I would like to search all orders with specified status and which was made yesterday after 3pm untill today 4pm. The query will run in different times (10am, 3pm, 5 pm... regardless).
So on example: if I run the query today (13.05.2014) I would like to get all orders made from 2014-12-05 15:00:00 untill 13-05-2015 16:00:00
The date is stored in format: YYYY-MM-DD HH:MM:SS
What I got is:
select *
from orders
where status = 'new'
and (
(
date_add(created_at, INTERVAL 1 day) = CURRENT_DATE()
and hour(created_at) >= 15
) /*1*/
or (
date(created_at) = CURRENT_DATE()
and hour(created_at) <= 16
) /*2*/
)
And I get only orders made today - like only the 2nd condition was taken into account.
I prefer not to use created >= '2014-05-12 16:00:00' (I will not use this query, someone else will).
When you add an interval of 1 day to the date/time, you still keep the time component. Use date() for the first condition:
where status = 'new' and
((date(date_add(created_at, INTERVAL 1 day)) = CURRENT_DATE() and
hour(created_at) >= 15
) /*1*/ or
(date(created_at) = CURRENT_DATE() and
hour(created_at) <= 16
) /*2*/
)
And alternative method is:
where status = 'new' and
(created_at >= date_add(CURRENT_DATE(), interval 15-24 hour) and
created_at <= date_add(CURRENT_DATE(), interval 16 hour)
)
The advantage of this approach is that all functions are moved to CURRENT_DATE(). This would allow MYSQL to take advantage of an index on created_at.