Count of past instances in an appended table - mysql

This is my desired output:
CampaignName CampaignDate UsersTargeted CountOfUsersBought
2x1 2018-11-24 1 (UserId 2) 1 (UserId 2)
3x2 2018-11-25 2 (Both) 1 (UserId 1)
'CountOfUsersBought' I want it to be Amongst All Targeted Users.
And the Table (Updated Daily) from where I get the data to fill the previous output has the following structure:
UserId EligibleForOffer(0,1) BoughtToday(0,1) Timestamp
1 0 0 2018-11-24
1 1 0 2018-11-25
1 1 1 2018-11-26
1 0 0 2018-11-27
2 1 0 2018-11-24
2 1 1 2018-11-25
2 1 0 2018-11-26
2 0 1 2018-11-27
I want to store on the variable 'CountOfUsersBought' the count of all the users that actually bought, not only today but all time. How would you go about doing this query?
Please note that users also buy without an offer, so I only want to count the past instances WHERE EligibleForOffer = 1 AND BoughtToday = 1 AND Timestamp <= 'CampaignDate'+ 1 day
I know for another table the users that are targeted for each campaign, I just want to keep for more than 'today' the count of users that took the offer that was given to them.

You can GROUP BY dates and use SUM the find how many users eligible for campaigns and use CASE to do your conditions. And bonus is MIN to find which specific user related with the condition is only one user match.
CREATE TABLE Campain
(
UserId INT
,EligibleForOffer BIT
,BoughtToday BIT
,Timestamp DATE
)
INSERT INTO Campain
VALUES
(1,0,0,'2018-11-24')
,(1,1,0,'2018-11-25')
,(1,1,1,'2018-11-26')
,(1,0,0,'2018-11-27')
,(2,1,0,'2018-11-24')
,(2,1,1,'2018-11-25')
,(2,1,0,'2018-11-26')
,(2,0,1,'2018-11-27')
SELECT Timestamp
,SUM(CAST(EligibleForOffer AS INT)) NumberOfUsersTargeted
,CASE WHEN SUM(CAST(EligibleForOffer AS INT))=1 THEN 'UserId-'+CAST(MIN(UserId) AS VARCHAR) WHEN SUM(CAST(EligibleForOffer AS INT))>1 THEN 'Multiple Users(Both)' ELSE 'No Target' END UsersTargetedDetail
,SUM(CAST(BoughtToday AS INT)) NumberOfBought
,CASE WHEN SUM(CAST(BoughtToday AS INT))=1 THEN 'UserId-'+CAST(MIN(UserId) AS VARCHAR) WHEN SUM(CAST(BoughtToday AS INT))>1 THEN 'Multiple Users(Both)' ELSE 'No Buying' END BoughtDetail
FROM Campain
GROUP BY Timestamp

Related

How to write single statement to retrieve last resume of user watching video if the complete date less than resume date?

I am sure this is pretty simple to do but I can’t do that. My problem :
I Have my sql database with one table keeping users video watching complete status(1) and resume(0). once the user is completed she/he again can watch the video the entry will be resume mode then status again insert 0 to this table.
TableName : sdbi_splms_videohit_track
Id videoid status userid watch_date
1 912230 0 1 2020-08-31 15:54:14
2 912230 1 1 2020-09-09 15:54:14
We need to retrieve only resume videos records the is status =0 and if the is status =1 and watch_date grater resume status=0.
Then First out put
it`s should retrieve 0 record because watch_date date greater that resume status
------ Watching this again on entry increase------------
Id videoid status userid watch_date
1 912230 0 1 2020-08-031 15:54:14
2 912230 1 1 2020-09-09 15:54:14
3 912230 0 1 2020-09-10 15:54:14
Out put the last one if resume again
3 912230 0 1 2020-09-10 15:54:14
My sql current query is below its always return resume record if completed date is greater resume date :
SELECT a.* FROM `sdbi_splms_videohit_track` as a WHERE a.videoid=912230 AND
`a`.`user_view_video` = '0' AND `a`.`user_id` = '1' GROUP BY b.videoid ORDER BY
MAX(a.date_created) DESC
Can you please guide me , if it is possible in single query.
It is difficult to help you with the information you are providing. Maybe you want to consider some changes in you database using at least three tables Like:
users_table
user_id int primary key autoincrement
user_name varchar(xxx)
...........
user_attribute(n)
videos_table
video_id int primary key autoincrement
video_name varchar(xxx)
...........
video_attribute(n)
video_track
id int primary_key autoincrement
video_id int
user_id int
pickup_date date
return_date date default null
This would allow you to select the videos taken from a user and not returned yet (your status 0) like.
SELECT vt.video_id, vt.video_name
FROM videos_track k
INNER JOIN users_table ut using (user_id)
INNER JOIN video_table vt using (video_id)
WHERE ISNULL(k.return_date)
AND ut.user_id = 1
So this query will give you all videos picked up by the user with user:id = 1 and yet not returned. If you need the videos picked up after certain date, you add this condition to the WHERE clause:
AND k.pickup_date <= limit_date
etc.
In other words, You'll be able to query your data with a variety of different questions.
Hope I got the essence of your issue so it may be af any help.

query with name and time spent with max views

I am having data like this database table:
cookie_id cookie_name cookie_url cookie_view date time
1 S265nEmXMz /test.php 1 23/11/16 02:51:39
2 S265nEmXMz /test.php 2 23/11/16 02:52:45
3 5h2Rae6YRO /test.php 1 23/11/16 02:52:58
I want to get cookie_name having max number of views and substraction of max to min time like
cookie_id cookie_name cookie_url cookie_view date time
1 S265nEmXMz /test.php 2 23/11/16 00:01:06
2 5h2Rae6YRO /test.php 1 23/11/16 02:52:58
You should use subtime to get the time difference. The other detail is that you need CASE for when you only have one cookie to avoid getting 0 as time.
SELECT `cookie_id`,
`cookie_name`,
`cookie_url`,
MAX(`cookie_view`) cookie_views,
`date`,
( CASE
WHEN Count(`cookie_id`) > 1 THEN Subtime(Max(`time`), Min(`time`))
ELSE time
end ) time_in
FROM `cookies`
GROUP BY `cookie_name`
ORDER BY cookie_id
Try:
SELECT cookie_name,
cookie_url,
Max(cookie_view) AS maxview,
Subtime(Max(time), Min(time)) AS spent,
date
FROM `cookie_table`
GROUP BY cookie_name

Creating view in mysql for a group of rows

I have a mysql table with the following columns
1. id - int, auto increasing;
2. loc_id - int;
3. group_id - int;
4. target_date - int (epoch timestamp for each date at 00:00);
5. required - int;
6. actual - int;
7. updated_on;
Records in the table will be inserted in blocks, where the number of inserted rows is equal to the number of groups (referenced by group_id). The number of groups is 3, i.e. each transaction will insert 3 rows:
loc_id + target_date + updated_on will be the same for each of the 3 rows;
the group_id will be 1 to 3 for each row;
required and actual will be specific for each row.
My question is: how to create a view so each block of 3 rows is represented as a single row in a table with columns as follows:
1. loc_id,
2. target_date,
3. required_for_group1,
4. actual_for_group1,
5. required_for_group2,
6. actual_for_group2,
7. required_for_group3,
8. actual_for_group3
9. updated_on
Many thanks in advance for your help!
With the example above is it possible to find which record is the latest for each loc_id/target_date if the cut-off point is 03:00AM for each target_date (which is always epoch at 00:00)? Something like an extra column to say "latest" for the entry "closest" to (target_date+10800). i tried adding a column "case when min((target_date+10800)-updated_on) then "latest" else 0 end", but did not quite make it work..
You can do get the results you want using conditional aggregation:
select loc_id, target_date,
max(case when group_id = 1 then required end) as required_1,
max(case when group_id = 1 then actual end) as actual_1,
max(case when group_id = 2 then required end) as required_2,
max(case when group_id = 2 then actual end) as actual_2,
max(case when group_id = 3 then required end) as required_3,
max(case when group_id = 3 then actual end) as actual_3,
updated_on
from table t
group by loc_id, target_date, updated_on;
You can put this statement into a view by putting create view <viewname> as before it.

Add 6 items together to give a total, but by not adding their values together

Bit of a newbie and probably a very basic question to you, but is driving me mad.
I have a mysql table. I have a record which has a record id, and six other fields which contain names of photographs.
So,
Record_id, photo1, photo2, photo3, photo4, photo5, photo6
I want have have the end result where I have a column called 'TOTAL' which shows the number of how many records have photographs in them as a TOTAL. So, Record 1 may have a total of 5 photographs, record 2 may have 3 photographs, and record 3 may have a total of NO records for that record etc?
Now some of the photographs names which are uploaded to the field may contain numbers, ie, photo244.jpg, or pic3993.jpg etc - so I don't want these numbers added together, I am just looking for whether the field has a name in it etc, and this would be counted as 1 to add to the total. So the end result in on the page is that record 13 (for example) has a total of 4 photographs etc - sorry if not a good explanation!
It may have something to do with SUM or COUNT, but have spent ages trying to get combination or correct key/syntax! Can anyone help please by giving an example of the mysql select statement - would be grateful!
I presume that if there is no photo, then the field photoX is null or is empty.
So use CASE for output 0 if the field is null or empty, 1 else.
SELECT Record_id
,
CASE WHEN (photo1 IS NULL OR photo1 = '') THEN 0 ELSE 1 END
+ CASE WHEN (photo2 IS NULL OR photo2 = '') THEN 0 ELSE 1 END
+ CASE WHEN (photo3 IS NULL OR photo3 = '') THEN 0 ELSE 1 END
+ CASE WHEN (photo4 IS NULL OR photo4 = '') THEN 0 ELSE 1 END
+ CASE WHEN (photo5 IS NULL OR photo5 = '') THEN 0 ELSE 1 END
+ CASE WHEN (photo6 IS NULL OR photo6 = '') THEN 0 ELSE 1 END
AS Total
FROM myTable
It will the best query:
SELECT
Record_id,
(6 - IFNULL(photo1,1) - IFNULL(photo2,1) - IFNULL(photo3,1) - IFNULL(photo4,1) - IFNULL(photo5,1) - IFNULL(photo6,1)) AS TOTAL
FROM
table
Something like this will give you a count by Photo1, Photo2, etc.:
SELECT
SUM(CASE WHEN photo1 IS NOT NULL THEN 1 END) AS Photo1Count,
SUM(CASE WHEN photo2 IS NOT NULL THEN 1 END) AS Photo2Count,
SUM(CASE WHEN photo3 IS NOT NULL THEN 1 END) AS Photo3Count,
SUM(CASE WHEN photo4 IS NOT NULL THEN 1 END) AS Photo4Count,
SUM(CASE WHEN photo5 IS NOT NULL THEN 1 END) AS Photo5Count
FROM MyTable
Something like this will count how many rows have at least one photograph:
SELECT SUM (
CASE WHEN
photo1 IS NOT NULL OR
photo2 IS NOT NULL OR
photo3 IS NOT NULL OR
photo4 IS NOT NULL OR
photo5 IS NOT NULL THEN 1 END)
FROM MyTable
Note that these queries are for grand totals. They don't show activity by row. If activity by row is needed, try the answers from Scorpi0 or Michael Sivolobov.

MySQL Query: count entries by status

I have a log table with following schema:
OperatorId - JobId - Status ( Good/Bad/Ugly )
Alex 6 Good
Alex 7 Good
James 6 Bad
Description: Whenever an operator works on a job, an entry is made along with Status. That's it.
Now I need a report like:
OperatorId - Good Count - Bad Count - Ugly Count
Alex 2 0 0
James 0 1 0
select operatorid,
sum(if(status="good",1,0)) as good,
sum(if(status="bad",1,0)) as bad,
sum(if(status="ugly",1,0)) as ugly
from table
group by operatorid
This is called a Pivot Table. It is done by setting a value 1 or 0 for each state and then summing them up:
SELECT
T.OperatorId,
SUM(T.GoodStat) AS Good,
SUM(T.BadStat) AS Bad,
SUM(T.UglyStat) AS Ugly
FROM
(
SELECT
CASE WHEN Status = 'Good' THEN 1 ELSE 0 END AS GoodStat,
CASE WHEN Status = 'Bad' THEN 1 ELSE 0 END AS BadStat,
CASE WHEN Status = 'Ugly' THEN 1 ELSE 0 END AS UglyStat,
OperatorId
FROM logTable T
)
GROUP BY T.OperatorId
If, like me, you prefer, whenever possible, to calculate counts with COUNT rather than with SUM, here's an alternative solution, which uses a method asked about in this thread:
SELECT
operatorid,
COUNT(status = 'good' OR NULL) as good,
COUNT(status = 'bad' OR NULL) as bad,
COUNT(status = 'ugly' OR NULL) as ugly
FROM table
GROUP BY operatorid