extract no of click between date range - mysql

i want to extract total no of click time wise (like week wise or month wise) from table bannerstatclick where bannerstatclick table have these column (idBannerStats: integer, Time: Timestamp, idCampaignBanner :char(36)). I want to calculate maximum time as current date then calculate before 30 days date and then find how many no of click between this date range it will not return any output ...
SELECT count(idCampaignBanner) AS TotalClicks
FROM newradium.BannerStatsClick
WHERE Time BETWEEN
(Select max(`Time`) FROM newradium.BannerStatsClick)
And
(select max(`Time`)- INTERVAL 30 DAY FROM newradium.BannerStatsClick);

Try this
set #max_time:= (SELECT max(`Time`) FROM newradium.BannerStatsClick );
SELECT count(idCampaignBanner) AS TotalClicks
FROM newradium.BannerStatsClick
WHERE Time BETWEEN date_add(#max_time, INTERVAL 30 DAY) and #max_time;

set #max_time:= (SELECT max(`Time`) FROM newradium.BannerStatsClick );
SELECT count(idCampaignBanner) AS TotalClicks
FROM newradium.BannerStatsClick
WHERE Time BETWEEN dateadd(day,-30,#max_time) and #max_time

Related

SQL MAX datetime - 1 day

I want to do a comparison between two dates. The highest date (currently via MAX datetime) is working, but I can't get the day after the highest date to compare the data with.
I'm using the following to get the data of the highest available date:
SELECT `datetime`, `standardSubscriptionDuration`,
SUM(`activeStandardPriceSubscriptions`) AS OneMonthActiveStandard
FROM `Subscription_totals`
WHERE `standardSubscriptionDuration` = '1 Month'
AND `datetime` = (SELECT MAX(`datetime`) AS Date FROM `Subscription_totals`)";
I already tried:
(SELECT MAX(`datetime`) -1 AS Date
But this won't give the result. How am I able to get the data of yesterday and eventually compare them?
I think that you want the following date arithmetics:
WHERE
`standardSubscriptionDuration` = '1 Month'
AND `datetime` = (
SELECT MAX(`datetime`) - interval 1 day AS Date FROM `Subscription_totals`
)

How to convert SQL result into percentage

I am trying to find the percentage increase in the last 7 days but I am a little stuck. Currently in the SQL query I have created, you can get the total of the new accounts in the last 7 days. But now, how can I improve to be able to return the result in percentage?
Here is the SQL query done so far.
Thanks
SELECT COUNT(DISTINCT account_type)
FROM account
WHERE date_created > NOW() - INTERVAL 7 DAY
You could create a temporary table with two columns, say 'old count' and 'new count'. Populate the table with the values you get from your SELECT queries.
Then, retrieve the values from the temp table to calculate the percentage difference and delete the temp table.
With purpose to run all in one query you may consider next query:
SELECT
/* Count for previous period. */
beforeCount,
/* Count for current period. */
afterCount,
/* Simple math, just calculating percentage. */
(beforeCount * 100) / afterCount AS percent
FROM (
SELECT
/* Select count for previous period. */
(
SELECT COUNT(DISTINCT account_type)
FROM account
WHERE date_created BETWEEN NOW() - INTERVAL 14 DAY AND NOW() - INTERVAL 7 DAY
) AS beforeCount,
/* Select count for current period. */
(
SELECT COUNT(DISTINCT account_type)
FROM account
WHERE date_created > NOW() - INTERVAL 7 DAY
) AS afterCount
) AS tmp
you can try below way calculate last 7days count and then calculate before 7days all then calculate percentage
select max(last7days_count) as last7days_count,
max(before7days_count) as before7days_count,
((max(before7days_count)*1.00)/max(last7days_count))*100.00 as percentage from
(
SELECT COUNT(DISTINCT account_type) as last7days_count, 0 as before7days_count
FROM account
WHERE date_created > NOW() - INTERVAL 7 DAY
union all
SELECT 0 as last7days_count COUNT(DISTINCT account_type) as before7days_count
FROM account
WHERE date_created < NOW() - INTERVAL 7 DAY
) as T
Conditional aggregation might work. Use a CASE to only count the new and another to only count the old accounts.
SELECT count(DISINCT CASE
WHEN date_created > NOW() - INTERVAL 7 DAY THEN
account_type
END)
/
count(DISTINCT CASE
WHEN date_created <= NOW() - INTERVAL 7 DAY THEN
account_type
END)
* 100 increase
FROM account;
With Temporary table you can do in like :
create temporary table storeCount IF NOT EXISTS (
oldCount INT(10) not null,
newCount INT(10) not null
);
insert into percentage (oldCount,newCount)
values
(SELECT COUNT(DISTINCT acc1.account_type)FROM account acc1, SELECT COUNT(DISTINCT acc2.account_type)
FROM account acc2 WHERE acc2.date_created > NOW() - INTERVAL 7 DAY);
select ((newCount/oldCount)*100) as percentage from storeCount;
drop temporary table IF EXISTS storeCount;
Assuming you have one row per account, you don't need distinct. I am guessing you want:
SELECT (SUM(date_created >= CURDATE() - INTERVAL 7 DAY) * 100/
SUM(date_created > CURDATE() - INTERVAL 7 DAY)
) as percent_increase
FROM account

extract no of click month wise

I am using MySQL. Here is my schema:
bannerstatclick(idBannerStats: integer, Time: Timestamp, idCampaignBanner :char(36))
I am trying to write a query to select the total no of click month wise by using count on idCampaignBanner.
this will not work it will give an error invalid use of group function.
iwill also try this using having clause but it also not work...
SELECT count(idCampaignBanner) AS TotalClicks ,max(`Time`) AS maxdate,(min(`Time`) + INTERVAL 30 DAY)as monthly
FROM newradium.BannerStatsClick
WHERE Time BETWEEN max(`Time`) AND ( max(`Time`)- INTERVAL 30 DAY)
Something like this should work (you need group by clause if you do aggregation)
select count(idCampaignBanner), MONTH(`Time`) as m
from newradium.BannerStatsClick
group by m
SELECT
count(idCampaignBanner) AS TotalClicks
, max(`Time`) AS maxdate
, (min(`Time`) + INTERVAL 30 DAY)as monthly
FROM newradium.BannerStatsClick
WHERE Time <= (Select max(`Time`) FROM newradium.BannerStatsClick)
And Time >= (Select max(`Time`) - INTERVAL 30 DAY FROM newradium.BannerStatsClick)
Technically could get rid of "Time <= (Select max(Time) FROM newradium.BannerStatsClick)", doesn't really affect the selection. But left in in case you needed different range in future

Average posts per hour on MySQL?

I have a number of posts saved into a InnoDB table on MySQL. The table has the columns "id", "date", "user", "content". I wanted to make some statistic graphs, so I ended up using the following query to get the amount of posts per hour of yesterday:
SELECT HOUR(FROM_UNIXTIME(`date`)) AS `hour`, COUNT(date) from fb_posts
WHERE DATE(FROM_UNIXTIME(`date`)) = CURDATE() - INTERVAL 1 DAY GROUP BY hour
This outputs the following data:
I can edit this query to get any day I want. But what I want now is the AVERAGE of each hour of every day, so that if on Day 1 at 00 hours I have 20 posts and on Day 2 at 00 hours I have 40, I want the output to be "30". I'd like to be able to pick date periods as well if it's possible.
Thanks in advance!
You can use a sub-query to group the data by day/hour, then take the average by hour across the sub-query.
Here's an example to give you the average count by hour for the past 7 days:
select the_hour,avg(the_count)
from
(
select date(from_unixtime(`date`)) as the_day,
hour(from_unixtime(`date`)) as the_hour,
count(*) as the_count
from fb_posts
where `date` >= unix_timestamp(current_date() - interval 7 day)
and created_on < unix_timestamp(current_date())
group by the_day,the_hour
) s
group by the_hour
Aggregate the information by date and hour, and then take the average by hour:
select hour, avg(numposts)
from (SELECT date(`date`) as day, HOUR(FROM_UNIXTIME(`date`)) AS `hour`,
count(*) as numposts
from fb_posts
WHERE DATE(FROM_UNIXTIME(`date`)) between <date1> and <date2>
GROUP BY date(`date`), hour
) d
group by hour
order by 1
By the way, I prefer including the explicit order by, since most databases do not order the results of a group by. Mysql happens to be one database that does.
SELECT
HOUR(FROM_UNIXTIME(`date`)) AS `hour`
, COUNT(`id`) \ COUNT(DISTINCT TO_DAYS(`date`)) AS avgHourlyPostCount
FROM fb_posts
WHERE `date` > '2012-01-01' -- your optional date criteria
GROUP BY hour
This gives you a count of all the posts, divided by the number of days, by hour.

Sum over Timerange overlapping to next day over several days

I am desperately trying to get sum of values from range of time over several days, the problem is the range overlaps a day e.g from 15:00 to 10:00 but unfortunately I cant come up with another solution than a loop over all days but there sure is a more elegant way to do this all in one query.
For a single day I have something like this
SELECT
(Date(`Date`)) AS `Date`, SUM(`Val`), `Ld_id`
FROM
(SELECT
`Date`, SUM(`Val`) AS `Val`, `Ld_id`
FROM
`tblVals`
INNER JOIN (SELECT
*
FROM
`tblDate`
WHERE
`Date` BETWEEN (SELECT CONCAT('2011-08-26 ', '14:31:00'))
AND (SELECT CONCAT('2011-08-27 ', '10:01:00'))
ORDER BY `Date` ASC) AS `A` ON `tblVals`.`date_id` = `A`.`date_id`
WHERE
`Ld_id` BETWEEN (SELECT
MIN(`Ld_id`)
FROM
`tblLr`
WHERE
`s_id` = '1') AND (SELECT
MAX(`Ld_id`)
FROM
`tblLr`
WHERE
`s_id` = '1')
GROUP BY ((60/30)*HOUR(`Date`)+FLOOR(MINUTE(`Date`)/30)),`Ld_id`
ORDER BY `Ld_id` ASC ,`Date` ASC) AS `A`
Group by `Ld_id`
Many thanks in advance for any hint`
If you want 15:00 to 14:59 the next day:
- subtract 15 hours from all timestamps
- group by the date part of the timestamp
If you want 15:00 to 10:00 the next day:
- subtract 15 hours from all timestamps
- discard all records where the timepart is now greater than 19:00
- group by the date part of the timestamp
In MySQL, I think it's something like this...
SELECT
DATE(DATE_SUB('Date', INTERVAL 15 HOUR)),
SUM(VAL)
FROM
tblVals
WHERE
TIME(DATE_SUB('Date', INTERVAL 15 HOUR)) < '19:00'
GROUP BY
DATE(DATE_SUB('Date', INTERVAL 15 HOUR))