MySql SELECT COUNT with two criterias - mysql

I'm trying to do a query that fetches data per the last hour and the two last hours. It's just a hits counter.
So I would like to get the resultset as follows:
id, page_url, last_hour_hits, two_last_hours_hits
The table is very simple:
id (autonumber)
page_url
time_stamp
I tried the query below:
SELECT
page_url,
COUNT(page_url) AS last_hour_hits
FROM stats
WHERE time_stamp > '2015-08-01 00:00:00'
GROUP BY page_url
('2015-08-01 00:00:00' is calculated for the last hour)
It works fine, but I have now idea how to add the 'two_last_hours' counter.
Thank you in advance.

With MySQL you can use the fact that boolean expression returns 1 for true and simplify the query to this:
SELECT
page_url
,sum(time_stamp > (now() - interval 1 hour)) as last_hour_hits
,sum(time_stamp > (now() - interval 2 hour)) as two_last_hours_hits
FROM stats
GROUP BY page_url;
This uses now() to get the current time and subtracts the interval as needed.

Just put your WHERE clause with two hours before ('2015-07-31 23:00:00') and a CASE WHEN to count for the last hour ('2015-08-01 00:00:00') :
SELECT
page_url,
COUNT(DISTINCT CASE WHEN time_stamp > '2015-08-01 00:00:00' THEN id ELSE NULL END) as last_hour_hits
COUNT(*) AS two_last_hours_hits
FROM stats
WHERE time_stamp > '2015-07-31 23:00:00'
GROUP BY page_url;

you can use join between two result sets- one for the one hour and the other for the two hours:
SELECT stats.page_url, last_hour_hits, last_two_hours_hits from
stats inner join (
SELECT page_url, COUNT(page_url) AS last_hour_hits
FROM stats WHERE time_stamp > '2015-08-01 00:00:00'
GROUP BY page_url ) as last_hour
on stats.page_url = last_hour.page_url
inner join (
SELECT page_url, COUNT(page_url) AS last_two_hours_hits
FROM stats WHERE time_stamp > '2015-07-31 23:00:00'
GROUP BY page_url ) as last_two_hours
on stats.page_url = last_two_hours.page_url

Related

I want to show 0 if no record found for a particular date

In mysql I have created a query where I want to get last one month data for each date, and if no record found for a particular date then it should show 0.
My mysql query is
select SUM(testviewaudit.action=1) AS view,
DATE(testviewaudit.datetime) from testviewaudit inner join tmtests on
testviewaudit.testid=tmtests.tsid where DATE(testviewaudit.datetime)
BETWEEN NOW() - INTERVAL 30 DAY AND NOW() group by
DATE(testviewaudit.datetime) order by DATE(testviewaudit.datetime)
asc;
well I have used this also but no success
select ifnull(SUM(testviewaudit.action=1), 0) AS view,
DATE(testviewaudit.datetime) from testviewaudit inner join tmtests on
testviewaudit.testid=tmtests.tsid where DATE(testviewaudit.datetime)
BETWEEN NOW() - INTERVAL 30 DAY AND NOW() group by
DATE(testviewaudit.datetime) order by DATE(testviewaudit.datetime)
asc;
still getting the same result
Try this:
select if(is null(testviewaudit.action), 0 , sum(testviewaudit.action=1)) AS view,
DATE(testviewaudit.datetime) from testviewaudit inner join tmtests on testviewaudit.testid=tmtests.tsid
where DATE(testviewaudit.datetime) BETWEEN NOW() - INTERVAL 30 DAY AND NOW() group by DATE(testviewaudit.datetime) order by DATE(testviewaudit.datetime) asc;
try to put the whole query in the IFNULL.
SELECT IFNULL( (SELECT field1 FROM table WHERE id = 1 ) ,'not found');

Query Help Between Date Range, but Not Recent

I'm know this can be written as a single SQL statement, but I just don't know how to do it. I have two separate queries. Ont that pulls all orders from a specific period of last year
SELECT * FROM `order` WHERE date_added BETWEEN '2014-10-01' AND '2014-11-01';
and one that pulls from the last month
SELECT * FROM `order` WHERE date_added BETWEEN DATE_SUB( now(), INTERVAL 1 MONTH) AND Now() ORDER BY date_added ASC
What I want to do is now join the two so that I only get the customer_id of orders that were placed inside of the date range last year (query 1), but haven't placed an order in the last month (query 2).
I know there is a way to set this up as a join, but my knowledge on sql join's is not very limited. Thanks for any help.
http://sqlfiddle.com/#!9/35ed0/1
SELECT * FROM `order`
WHERE date_added BETWEEN '2014-10-01' AND '2014-11-01'
AND customer_id NOT IN (
SELECT DISTINCT customer_id FROM `order`
WHERE date_added BETWEEN DATE_SUB( now(), INTERVAL 1 MONTH) AND Now())
UPDATE If you need only 1 records per customer_id, here is an example . It is not very best from performance perspective. But it returns only last (according to the date_added column) order per customer.
SELECT t.*,
if(#fltr=customer_id, 0, 1) fltr,
#fltr:=customer_id
FROM (SELECT *
FROM `order`
WHERE date_added BETWEEN '2014-10-01' AND '2014-11-01'
AND customer_id NOT IN (
SELECT DISTINCT customer_id FROM `order`
WHERE date_added BETWEEN DATE_SUB( now(), INTERVAL 1 MONTH) AND Now())
ORDER BY customer_id, date_added DESC
) t
HAVING (fltr=1);
I usually use a correlated not exists predicate for this as I feel that it corresponds well with the intent of the question:
SELECT *
FROM `order` o1
WHERE date_added BETWEEN '2014-10-01' AND '2014-11-01'
AND NOT EXISTS (
SELECT 1
FROM `order` o2
WHERE date_added BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()
AND o1.customer_id = o2.customer_id
);
I like to approach these questions using group by and having. You are looking for customer ids, so:
select o.customer_id
from orders o
group by o.customer_id
having sum(date_added BETWEEN '2014-10-01' AND '2014-11-01') > 0 and
sum(date_added BETWEEN DATE_SUB( now(), INTERVAL 1 MONTH) AND Now()) = 0;

Count number of entries in time interval 1 that appear in time interval 2 - SQL

I am new here and tried to look up the answer to my question but couldn't find anything on it. I am currently learning how to work with SQL queries and am wondering how I can count the amount of unique values that appear in two time intervals?
I have two columns; one is the timestamp while the other is a customer id. What I want to do is to check, for example, the amount of customers that appear in time interval A, let's say January 2014 - February 2014. I then want to see how many of these also appear in another time interval that i specify, for example February 2014-April 2014. If the total sample were 2 people who both bought something in january while only one of them bought something else before the end of April, the count would be 1.
I am a total beginner and tried the query below but it obviously won't return what I want because each entry only having one timestamp makes it not possible to be in two intervals.
SELECT
count(customer_id)
FROM db.table
WHERE time >= date('2014-01-01 00:00:00')
AND time < date('2014-02-01 00:00:00')
AND time >= date('2014-02-01 00:00:00')
AND time < date('2014-05-01 00:00:00')
;
Try this.
select count(distinct t.customer_id) from Table t
INNER JOIN Table t1 on t1.customer_id = t.customer_id
and t1.time >= '2014-01-01 00:00:00' and t1.time<'2014-02-01 00:00:00'
where t.time >='2014-02-01 00:00:00' and t.time<'2014-05-01 00:00:00'
Here's one method of doing this with conditional grouping in an inner-select.
Select Case
When GroupBy = 1 Then 'January - February 2014'
When GroupBy = 2 Then 'February - April 2014'
End As Period,
Count (Customer_Id) As Total
From
(
SELECT Customer_Id,
Case
When Time Between '2014-01-01' And '2014-02-01' Then 1
When Time Between '2014-02-01' And '2014-04-01' Then 2
Else -1
End As GroupBy
From db.Table
) D
Where GroupBy <> -1
Group By GroupBy
Edit: Sorry, misread the question. This will show you those that overlap those two time ranges:
Select Count(Customer_Id)
From db.Table t1
Where Exists
(
Select Customer_Id
From db.Table t2
Where t1.customer_id = t2.customer_id
And t2.Time Between '2014-02-01' And '2014-04-01'
)
And t1.Time Between '2014-01-01' And '2014-02-01'

match timestamp with date in MYSQL using PHP

I have a table
id user Visitor timestamp
13 username abc 2014-01-16 15:01:44
I have to 'Count' total visitors for a 'User' for last seven days group by date(not timestamp)
SELECT count(*) from tableA WHERE user=username GROUPBY __How to do it__ LIMIT for last seven day from today.
If any day no visitor came so, no row would be there so it should show 0.
What would be correct QUERY?
There is no need to GROUP BY resultset, you need to count visits for a week (with unspecified user). Try this:
SELECT
COUNT(*)
FROM
`table`
WHERE
`timestamp` >= (NOW() - INTERVAL 7 DAY);
If you need to track visits for a specified user, then try this:
SELECT
DATE(`timestamp`) as `date`,
COUNT(*) as `count`
FROM
`table`
WHERE
(`timestamp` >= (NOW() - INTERVAL 7 DAY))
AND
(`user` = 'username')
GROUP BY
`date`;
MySQL DATE() function reference.
Try this:
SELECT DATE(a.timestamp), COUNT(*)
FROM tableA a
WHERE a.user='username' AND DATEDIFF(NOW(), DATE(a.timestamp)) <= 7
GROUP BY DATE(a.timestamp);
i think it's work :)
SELECT Count(*)
from table A
WHERE user = username AND DATEDIFF(NOW(),timestamp)<=7

MySQL COUNT DISTINCT

I'm trying to collect the number of distinct visits in my cp yesterday, then count them.
SELECT
DISTINCT `user_id` as user,
`site_id` as site,
`ts` as time
FROM
`cp_visits`
WHERE
ts >= DATE_SUB(NOW(), INTERVAL 1 DAY)
For some reason this is pulling multiple results with the same site id....how do i only pull and count the distinct site_id cp logins?
Select
Count(Distinct user_id) As countUsers
, Count(site_id) As countVisits
, site_id As site
From cp_visits
Where ts >= DATE_SUB(NOW(), INTERVAL 1 DAY)
Group By site_id
Overall
SELECT
COUNT(DISTINCT `site_id`) as distinct_sites
FROM `cp_visits`
WHERE ts >= DATE_SUB(NOW(), INTERVAL 1 DAY)
Or per site
SELECT
`site_id` as site,
COUNT(DISTINCT `user_id`) as distinct_users_per_site
FROM `cp_visits`
WHERE ts >= DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY `site_id`
Having the time column in the result doesn't make sense - since you are aggregating the rows, showing one particular time is irrelevant, unless it is the min or max you are after.
You need to use a group by clause.
SELECT site_id, MAX(ts) as TIME, count(*) group by site_id