Reduce number of mysql count query for different time interval - php

I am using below query:
$select_jan1 = "SELECT count(*) FROM users WHERE timeStamp BETWEEN '2015-01-01' and '2015-01-31'";
$select_feb1 = "SELECT count(*) FROM users WHERE timeStamp BETWEEN '2015-02-01' and '2015-02-28'";
$select_mar1 = "SELECT count(*) FROM users WHERE timeStamp BETWEEN '2015-03-01' and '2015-03-31'";
Is there way to put this 3 query in one ?
Thank You

You can put the values in three columns, using conditional aggregation:
SELECT SUM(timeStamp BETWEEN '2015-01-01' and '2015-01-31') as cnt_201501,
SUM(timeStamp BETWEEN '2015-02-01' and '2015-02-28') as cnt_201502,
SUM(timeStamp BETWEEN '2015-03-01' and '2015-03-31') as cnt_201503
FROM users;
Do note that this logic ignores that values on the last day of each month. Better logic is:
SELECT SUM(timeStamp >= '2015-01-01' and timestamp < '2015-02-01') as cnt_201501,
SUM(timeStamp >= '2015-02-01' and timestamp < '2015-03-01') as cnt_201502,
SUM(timeStamp >= '2015-03-01' and timestamp < '2015-04-01') as cnt_201503
FROM users
WHERE timeStamp >= '2015-01-01' and timeStamp < '2015-04-01';

With whole months, I do so:
SELECT
count(*)
FROM
(SELECT
year(timestamp) AS year_, month(timestamp) AS month_
FROM
users) s
WHERE
s.year_ = 2015 AND s.month_ >=4

Related

how can i write as one query to get count in mysql

I want to get the today count of users and yesterday's users count for that i want to write only one query how can i do that..?
these are my queries I want only one query:
SELECT COUNT(*) FROM visitors group by visited_date ORDER by visited_date DESC limit 1,1 as todayCount
SELECT COUNT(*) FROM visitors group by visited_date ORDER by visited_date DESC limit 1,0 as yesterdayCount
My expected results or only 2 columns
todayCount yesterdayCount
2 4
This should do the trick:
SELECT COUNT(CASE
WHEN visited_date = CURDATE() THEN 1
END) AS todayCount ,
COUNT(CASE
WHEN visited_date = CURDATE() - INTERVAL 1 DAY THEN 1
END) AS yesterdayCount
FROM visitors
WHERE visited_date IN (CURDATE(), CURDATE() - INTERVAL 1 DAY)
GROUP BY visited_date
ORDER by visited_date
If you know the current and previous date, then you can do:
SELECT SUM(visited_date = CURDATE()) as today,
SUM(visited_date = CURDATE() - interval 1 day) as yesterday
FROM visitors
WHERE visited_date >= CURDATE() - interval 1 day;
If you don't know the two days, then you can do something similar, getting the latest date in the data:
SELECT SUM(v.visited_date = m.max_vd) as today,
SUM(v.visited_date < m.max_vd) as yesterday
FROM visitors v CROSS JOIN
(SELECT MAX(v2.visited_date) as max_vd FROM visitors v2) as m
WHERE v.visited_date >= m.max_vd - interval 1 day
Just try this simple query
select visited_date as date, COUNT(*) as count from `visitors`
group by `visited_date` order by `visited_date` asc
It will produce output as
It will work for you.
Try this:
$sqlToday = "Select COUNT(*) FROM menjava WHERE DATE(date_submitted)=CURRENT_DATE()";
$sqlYesterday = "Select COUNT(*) FROM menjava WHERE DATE(dc_created) = CURDATE() - INTERVAL 1 DAY";

MySQL incorrect result on group by

I am counting unique ip visits for user account. I am getting different result on checking total visits vs grouped user account visits
My table structure is like this
id userid userip status date
1 xxxx 11111 1 unix timestamp
2 yyyy 11122 1 unix timestamp
3 zzzz 11133 1 unix timestamp
4 cccc 11144 1 unix timestamp
I am doing query like this
$date1 = strtotime("yesterday midnight");
$date2 = strtotime("today midnight");
SELECT `userid`, COUNT(DISTINCT `userip`) AS `total` FROM `stats`
WHERE (`date` >= $date1 AND `date` < $date2) AND `status`=1
This gives result as 5644
But when I group by userid result is different
$date1 = strtotime("yesterday midnight");
$date2 = strtotime("today midnight");
SELECT `userid`, COUNT(DISTINCT `userip`) AS `total` FROM `stats`
WHERE (`date` >= $date1 AND `date` < $date2) AND `status`=1 GROUP BY `userid`
while($row=mysqli_fetch_assoc($result)){
$total=$total+$row['total'];
}
This gives result as 6312
Please see why there is different result on group by
Thanks
EDIT
Result is correct if I don't count DISTINCT
its obvious that the count wont match as in your first query you have used distinct with count now the rows fetched is 5644.
Which may have count with the values like 2,3,4,5 so if you need the same count as group by you need to add all the count column which will be same as your group by query
if you need unique users the use below query
SELECT DISTINCT `userip` AS `userip` FROM `stats`
WHERE (`date` >= $date1 AND `date` < $date2) AND `status`=1
For user with unique ip
SELECT userid,userip from stats GROUP BY userip HAVING COUNT(*) >=1

Select Distinct records from a Timestamp row using day only from MySQL table

I'm trying to query only distinct dates from my table (ignoring the times) which uses timestamp for the date format (should I use a better format?). Here is my query, but it doesn't seem to work:
$query = "
SELECT DISTINCT DATE(event_date)
FROM schedule
WHERE DATE(event_date) >= CURDATE()
ORDER BY event_date ASC LIMIT 4
";
"event_date" is my timestamp row in the database.
You may have a problem with the order by. How about this?
SELECT DATE(event_date)
FROM schedule
WHERE event_date >= CURDATE()
GROUP BY DATE(event_date)
ORDER BY DATE(event_date) ASC
LIMIT 4;

MySQL Query Date Errors

I have this query that indexes my images and orders them by popularity but I cant make the user to choose the interval cause there's something wrong with the query:
switch($Data['data']){
case 'daily':$QueryDate='=CURDATE()';break;
case 'weekly':$QueryDate=' BETWEEN SUBDATE(CURDATE(), INTERVAL 7 DAYS) AND NOW()';break;
case 'monthly':$QueryDate='>CURDATE() - INTERVAL 31 DAYS';break;
default: Core::redirect('image/browse/daily/1');break;
}
$IMGDB = new Database('images');
$query = "SELECT *, (derived.`likes` * 2 + derived.`views`) as `popularity` from
(SELECT *,
(SELECT COUNT(*) FROM `likes` WHERE `like`=I.id AND `date`".$QueryDate.") AS `likes`,
(SELECT SUM(`views`) FROM `views` WHERE `id`=I.id AND `date`".$QueryDate.") AS `views`
FROM images AS I
) AS derived
where 1 ORDER BY `popularity` DESC ";
Only the daily case works.
Here is the error:
SQL Error (1064): You have an error in your SQL syntax;..... to use near 'DAYS) AND NOW()) AS likes, (SELECT SUM(views) FROM views WHERE id= I.id A
The correct syntax for specifying an interval of days uses the DAY keyword. You've used DAYS in:
BETWEEN SUBDATE(CURDATE(), INTERVAL 7 DAYS) AND NOW()
and:
> CURDATE() - INTERVAL 31 DAYS

Selecting in between won't work with MySQL?

I have a quick and asap issue.
SELECT `deals`.*
FROM `deals`
WHERE
`is_featured` = 1 AND
`status` = 'active' AND
CURDATE() BETWEEN start_date AND DATE_ADD(end_date, INTERVAL 1 DAY)
ORDER BY `end_date` DESC
LIMIT 1
Is this right?
start_date is "2012-01-11 00:00:00" and end_date is "2012-01-11 23:59:59".
This is what I wish to show:
I want to show the dealoffer that is between the current datetime and if the is_featured is 1 and status are "active".
(CURDATE() gives me only date, not time, is this the problem? How can I get current datetime in MySql?).
It should only pick one deal and this deal should be the one with the closest end date from current datetime.
Here is your original query
SELECT `deals`.* FROM `deals`
WHERE `is_featured` = 1
AND `status` = 'active'
AND CURDATE() BETWEEN start_date AND DATE_ADD(end_date, INTERVAL 1 DAY)
ORDER BY `end_date` DESC
LIMIT 1;
Replace the BETWEEN with this
SELECT `deals`.* FROM `deals`
WHERE `is_featured` = 1
AND `status` = 'active'
AND start_date >= (CURDATE() + INTERVAL 0 SECOND)
AND start_date <= (end_date + INTERVAL 1 DAY)
ORDER BY `end_date` DESC
LIMIT 1;
and add this index
ALTER TABLE deals ADD INDEX (is_featured,status,start_date,end_date);
Use now() to get the date and time.
You could use the curtime() function to retrieve the current time.

Categories