SQL Social - Online Users - mysql

I've got a table
CREATE TABLE `tbl_users` (
`user_id` int(11) NOT NULL auto_increment,
`user_username` tinytext NOT NULL,
`user_password` tinytext NOT NULL,
`user_email` tinytext NOT NULL,
`user_enabled` tinyint(4) NOT NULL default '1',
`user_verified` tinyint(4) NOT NULL default '0',
`user_verified_date` datetime NOT NULL default '0000-00-00 00:00:00',
`user_signup_date` datetime NOT NULL default '0000-00-00 00:00:00',
`user_login_date` datetime default NULL,
`user_status` mediumtext NOT NULL,
`user_online` tinyint(4) NOT NULL default '0',
PRIMARY KEY (`user_id`)
)
Every time a user visits the website user_login_date updates and user_online is set to 1, which means he's online.
What query can I send to switch user_online to 0 (offline) if user's last visit was 10 minutes ago?
I've already done like that
UPDATE tbl_users SET user_online = '0' WHERE (NOW() - user_login_date) > INTERVAL 10 minute
But that didn't help.

You should do the calculations on the constants so that an index on user_login_date can be used:
UPDATE tbl_users
SET user_online = '0'
WHERE NOW() - INTERVAL 10 MINUTE > user_login_date

Related

MySQL - Fix my poor performing UPDATE?

I have an event which fires periodically to 'abort' some abandoned games (a simple matching server).
This update is proving very (VERY) slow and I'm looking for advice on doing this better.
Problematic Update:
UPDATE user SET skill=skill+
(SELECT count(participant_1) * 25 FROM matches
WHERE score_2 IS NULL
AND score_2_time IS NOT NULL
AND participant_1=user.id
AND score_2_time < (NOW() - INTERVAL 1 HOUR)
AND status=0);
Matches table:
matches CREATE TABLE `matches` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `match_hash` varchar(64) DEFAULT NULL,
 `skill` int(10) unsigned DEFAULT NULL,
 `status` int(10) unsigned DEFAULT NULL,
 `participant_1` int(10) unsigned DEFAULT NULL,
 `score_1` int(10) unsigned DEFAULT NULL,
 `score_1_time` timestamp NULL DEFAULT NULL,
 `participant_1_rematched` tinyint(4) DEFAULT NULL,
 `participant_2` int(10) unsigned DEFAULT NULL,
 `score_2` int(10) unsigned DEFAULT NULL,
 `score_2_time` timestamp NULL DEFAULT NULL,
 `participant_2_rematched` tinyint(4) DEFAULT NULL,
 `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
 `finished_at` timestamp NULL DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=40667 DEFAULT CHARSET=latin1
User table:
user CREATE TABLE `user` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `name` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
 `skill` int(10) unsigned DEFAULT NULL,
 `created` timestamp NOT NULL DEFAULT current_timestamp(),
 PRIMARY KEY (`id`),
 UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1876 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Any guidance is greatly appreciated.
You need more indexes on the matches table, certainly at least participant_1, and whatever else is mentioned in the WHERE clause that helps. Probably participant_1 should be a foreign key into user.id for integrity reasons.
Try this query:
update user a join (SELECT participant_1,count(participant_1) * 25 as count FROM matches
WHERE score_2 IS NULL
AND score_2_time IS NOT NULL
AND score_2_time < (NOW() - INTERVAL 1 HOUR)
AND status=0 group by participant_1) b on a.id=b.participant_1 SET a.skill=a.skill+b.count

SQL UPDATE updates more columns than the number of columns set in MySQL Query

I have a table called notifier with 11 columns :
CREATE TABLE `notifier` (
`NUM_UTILISATEUR` int(32) UNSIGNED NOT NULL,
`NUM_NOTIFICATION` int(32) UNSIGNED NOT NULL,
`LU` tinyint(1) NOT NULL,
`DATE_NOTIFIER` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`NUM_PENSEE` int(32) NOT NULL,
`NUM_CONTRIBUTION` int(32) NOT NULL,
`NUM_COMMENTAIRE` int(32) UNSIGNED NOT NULL,
`CODE_NOTIF` int(11) NOT NULL,
`VU` tinyint(1) NOT NULL,
`DATE_VU` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`DATE_LU` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
And I want to update only 2 columns : VU and DATE_LU. For that, I ran this mysql query :
UPDATE notifier
SET VU=1, DATE_LU = date('Y-m-d H:i:s')
WHERE NUM_UTILISATEUR=130
AND NUM_PENSEE = 113
AND CODE_NOTIF=2
AND NUM_CONTRIBUTION=439
AND NUM_COMMENTAIRE=600"
But It updates 3 columns : VU, DATE_VU and DATE_LU, instead of the 2 (VU, DATE_LU) I wanted! I even replace date('Y-m-d H:i:s') by NOW() but the issue remains
Any idea of what is going on ?

Mysql: How to get a result for each day in between an start and an end date from a table that contains also a start and an end date?

I have a start date and an end date. For each day between start and end date I like to get a result, even if there are no results within my stats table.
The best suggestion to solve this is a stored procedure what creates a temporary table for each date (day) so that I could create a join.
BEGIN
declare d datetime;
create temporary table joindates (d date not null);
SET d = fkstartdate;
WHILE d <= fkenddate DO
insert into joindates (d) values (d);
set d = date_add(d, interval 1 day);
END WHILE;
SELECT * FROM `joindates` AS tempt LEFT JOIN `radacct` AS stats
ON stats.acctstarttime <= tempt.d AND (stats.acctstoptime >= tempt.d OR stats.acctstoptime IS NULL) AND calledstationid = calledstationid
ORDER BY tempt.d ASC;
drop temporary table joindates;
END
The join is not finalized now (just for testing). But as you see, the join would be perfect if the "radacct" table would use just one date col. Than I could easily create a JOIN by using the = operator for ON.
Now the "radacct" however is using acctstarttime and acctstoptime for there entries (I can not modify this table, is given by the radius server) both are datetime types.
So in my query I need all entries between my start and stop date where acctstarttime has started in the past or within my time period. And acctstoptime is within my time period, after my time period or NULL (active session).
The problem with my JOIN solution: Its slow as hell
Do you may have any faster query ideas please?
Thanks
Appendix1: It is very important that I get a result for each entry on each day that matches my period of days, even if acctstarttime to acctstoptime goes over multiple days. So that I always get all users online.
Appendix2:
As requested, the full table structure of "radacct" – the accounting table of the freeradius MySql module …
CREATE TABLE `radacct` (
`radacctid` bigint(21) NOT NULL AUTO_INCREMENT,
`acctsessionid` varchar(64) NOT NULL DEFAULT '',
`acctuniqueid` varchar(32) NOT NULL DEFAULT '',
`username` varchar(64) NOT NULL DEFAULT '',
`groupname` varchar(64) NOT NULL DEFAULT '',
`realm` varchar(64) DEFAULT '',
`nasipaddress` varchar(15) NOT NULL DEFAULT '',
`nasportid` varchar(15) DEFAULT NULL,
`nasporttype` varchar(32) DEFAULT NULL,
`acctstarttime` datetime DEFAULT NULL,
`acctstoptime` datetime DEFAULT NULL,
`acctsessiontime` int(12) unsigned DEFAULT NULL,
`acctauthentic` varchar(32) DEFAULT NULL,
`connectinfo_start` varchar(50) DEFAULT NULL,
`connectinfo_stop` varchar(50) DEFAULT NULL,
`acctinputoctets` bigint(20) DEFAULT NULL,
`acctoutputoctets` bigint(20) DEFAULT NULL,
`calledstationid` varchar(50) NOT NULL DEFAULT '',
`callingstationid` varchar(50) NOT NULL DEFAULT '',
`acctterminatecause` varchar(32) NOT NULL DEFAULT '',
`servicetype` varchar(32) DEFAULT NULL,
`framedprotocol` varchar(32) DEFAULT NULL,
`framedipaddress` varchar(15) NOT NULL DEFAULT '',
`acctstartdelay` int(12) unsigned DEFAULT NULL,
`acctstopdelay` int(12) unsigned DEFAULT NULL,
`xascendsessionsvrkey` varchar(10) DEFAULT NULL,
PRIMARY KEY (`radacctid`),
UNIQUE KEY `acctuniqueid` (`acctuniqueid`),
KEY `username` (`username`),
KEY `framedipaddress` (`framedipaddress`),
KEY `acctsessionid` (`acctsessionid`),
KEY `acctsessiontime` (`acctsessiontime`),
KEY `acctstarttime` (`acctstarttime`),
KEY `acctstoptime` (`acctstoptime`),
KEY `nasipaddress` (`nasipaddress`)
) ENGINE=InnoDB AUTO_INCREMENT=2041894 DEFAULT CHARSET=latin1

MySQL - Optimise Query

I have been left with a report which returns rows at an awfully slow rate. I feel I need to redo without so many or any sub-queries. But I am having a complete brain freeze to how to attempt this.
I have looked at indexes and the keys are not unique enough, which forces a full table scan time. Is there any way I can pull certain information from the other tables using a separate query, adding that as a variable and use it in the main query. As really the result of this query is only a few lines.
Are there any tips or tricks, that I could use to optimise or correct this SQL statement to speed it up.
(EDIT) I have added some create code for the tables.
SELECT
case when (select count(ag.`PKEY`) - count(ag.`ANSWERTIME`) from acdcallinformation ag
where (ag.`COMPLETED`) = 1 and answertime is null and time(ag.INSTIME) and DATE_FORMAT(DATEOFCALL,'%Y-%m-%d') >= date(now()) and ag.skillid = acdcallinformation.skillid) is null
then 0
else
(select count(ag.`PKEY`) - count(ag.`ANSWERTIME`) from acdcallinformation ag where (ag.`COMPLETED`) = 1
and answertime is null and DATE_FORMAT(DATEOFCALL,'%Y-%m-%d') >= date(now()) and ag.skillid = acdcallinformation.skillid)
end as LostCalls,
case when count(acdcallinformation.idleonqueue) is null then 0 else count(acdcallinformation.idleonqueue) end as CountCallsACD,
case when count(acdcallinformation.`ANSWERTIME`) is null then 0 else count(acdcallinformation.`ANSWERTIME`) end AS acdcallinformation_ANSWERED,
(select skillinfo.skillname from skillinfo where skillinfo.pkey = acdcallinformation.skillid) AS acdcallinformation_SKILLIDTEXT,
(select count(pkey) from acdcallinformation age
where DATE_FORMAT(DATEOFCALL,'%Y-%m-%d') >= date(now()) and age.skillid = acdcallinformation.skillid and (age.`COMPLETED`) = 0 and answertime is null
and SKILLID in (select SKILLID
from
callcenterinformation
where time > (now() - INTERVAL 5 SECOND) and callswaiting > 0)) as Waiting,
-- count(acdcallinformation.`PKEY`) as CallsWaiting,
acdcallinformation.`DATEOFCALL` AS acdcallinformation_DATEOFCALL,
acdcallinformation.`FIRSTRINGONQUEUE` AS acdcallinformation_FIRSTRINGONQUEUE,
case when acdcallinformation.`CONNECTTIME` is null then time('00:00:00') else acdcallinformation.`CONNECTTIME` end AS acdcallinformation_CONNECTTIME,
acdcallinformation.`CALLSTATEBEFOREIDLE` AS acdcallinformation_CALLSTATEBEFOREIDLE,
case when acdcallinformation.`AGENTRINGTIME` is null then time('00:00:00') else acdcallinformation.`AGENTRINGTIME` end AS acdcallinformation_AGENTRINGTIME,
acdcallinformation.`IDLEONQUEUE` AS acdcallinformation_IDLEONQUEUE,
acdcallinformation.`DDI` AS acdcallinformation_DDI,
acdcallinformation.`CLIP` AS acdcallinformation_CLIP,
acdcallinformation.`SKILLID` AS acdcallinformation_SKILLID,
acdcallinformation.`ACTIONTYPE` AS acdcallinformation_ACTIONTYPE,
acdcallinformation.`ACTIONDESTINATION` AS acdcallinformation_ACTIONDESTINATION,
acdcallinformation.`COMPLETED` AS acdcallinformation_COMPLETED,
acdcallinformation.`HANDLED` AS acdcallinformation_HANDLED,
acdcallinformation.`CONFIRMED` AS acdcallinformation_CONFIRMED,
(
SELECT
cal.`AGENTSREADY` AS callcenterinformation_AGENTSREADY
FROM
`callcenterinformation` cal
WHERE cal.skillid <> 1 and acdcallinformation.skillid = skillid order by pkey desc limit 1,1) as agentsready
FROM
`acdcallinformation` acdcallinformation
where DATE_FORMAT(DATEOFCALL,'%Y-%m-%d') >= date(now()- interval 1 day )
group by (select skillinfo.skillname from skillinfo where skillinfo.pkey = acdcallinformation.skillid);
CREATE TABLE `callcenterinformation` (
`INSTIME` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`PKEY` INT(11) NOT NULL,
`SKILLID` INT(11) NULL DEFAULT '0',
`DATE` DATE NULL DEFAULT NULL,
`TIME` TIME NULL DEFAULT NULL,
`AGENTSLOGGEDIN` INT(11) NULL DEFAULT '0',
`AGENTSREADY` INT(11) NULL DEFAULT '0',
`AGENTSRINGING` INT(11) NULL DEFAULT '0',
`AGENTSCONNECTED` INT(11) NULL DEFAULT '0',
`AGENTSINPAUSE` INT(11) NULL DEFAULT '0',
`AGENTSINWRAPUP` INT(11) NULL DEFAULT '0',
`CALLSWAITING` INT(11) NULL DEFAULT '0',
`COMPLETED` TINYINT(1) NULL DEFAULT '0',
`HANDLED` TINYINT(1) NULL DEFAULT '0',
`CONFIRMED` TINYINT(1) NULL DEFAULT '0',
PRIMARY KEY (`PKEY`),
INDEX `DATE` (`DATE`),
INDEX `TIME` (`TIME`),
INDEX `SKILLID` (`SKILLID`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;
CREATE TABLE `acdcallinformation` (
`INSTIME` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`PKEY` INT(11) NOT NULL,
`DATEOFCALL` DATE NULL DEFAULT NULL,
`FIRSTRINGONQUEUE` TIME NULL DEFAULT NULL,
`CONNECTTIME` TIME NULL DEFAULT NULL,
`CALLSTATEBEFOREIDLE` INT(11) NULL DEFAULT '0',
`AGENTRINGTIME` TIME NULL DEFAULT NULL,
`ANSWERTIME` TIME NULL DEFAULT NULL,
`IDLEONQUEUE` TIME NULL DEFAULT NULL,
`DDI` TEXT NULL,
`CLIP` TEXT NULL,
`SKILLID` INT(11) NULL DEFAULT '0',
`ACTIONTYPE` INT(11) NULL DEFAULT '0',
`ACTIONDESTINATION` TEXT NULL,
`COMPLETED` TINYINT(1) NULL DEFAULT '0',
`HANDLED` TINYINT(1) NULL DEFAULT '0',
`CONFIRMED` TINYINT(1) NULL DEFAULT '0',
PRIMARY KEY (`PKEY`),
INDEX `DATEOFCALL` (`DATEOFCALL`),
INDEX `IDLEONQUEUE_HANDLED` (`IDLEONQUEUE`, `HANDLED`),
INDEX `SKILLID` (`SKILLID`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;
CREATE TABLE `skillinfo` (
`INSTIME` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`PKEY` INT(11) NOT NULL,
`SKILLNAME` TEXT NULL,
`CLIP` TEXT NULL,
`WRAPUPTIMELENGTH` INT(11) NULL DEFAULT '0',
`MAXRINGTIMELENGTH` INT(11) NULL DEFAULT '0',
`FORCEDTICKET` TINYINT(1) NULL DEFAULT '0',
`STATEAFTERWRAPUP` INT(11) NULL DEFAULT '0',
`STATEAFTERUNANSWEREDCALL` INT(11) NULL DEFAULT '0',
`ACTIONTYPE` INT(11) NULL DEFAULT '0',
`ACTIONDESTINATION` TEXT NULL,
`DEFLECTAFTERCOURTESY` TINYINT(1) NULL DEFAULT '0',
`MAXOVERALLRINGTIMELENGTH` INT(11) NULL DEFAULT '0',
`AUTOCLIP` TINYINT(1) NULL DEFAULT '0',
`OUTGOINGSETTINGSACTIVE` TINYINT(1) NULL DEFAULT '0',
`NUMPLANIDENTIFIER` INT(11) NULL DEFAULT '0',
`TYPEOFNUMBER` INT(11) NULL DEFAULT '0',
`CLIR` INT(11) NULL DEFAULT '0',
`OUTGOINGROUTEID` INT(11) NULL DEFAULT '0',
`USELASTAGENT` TINYINT(1) NULL DEFAULT '0',
`CLIPROUTINGACTIVE` TINYINT(1) NULL DEFAULT '0',
`USETHRESHOLD` TINYINT(1) NULL DEFAULT '0',
`NORMALLOADTHRESHOLD` INT(11) NULL DEFAULT '0',
`OVERLOADTHRESHOLD` INT(11) NULL DEFAULT '0',
`STATEAFTERFORWARD` INT(11) NULL DEFAULT '0',
`CALLDISTTYPE` INT(11) NULL DEFAULT '0',
`USERGROUPID` INT(11) NULL DEFAULT '0',
`EXTERNALCONTROL` TINYINT(1) NULL DEFAULT '0',
`LASTAGENTLIMIT` INT(11) NULL DEFAULT '0',
PRIMARY KEY (`PKEY`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;
Too be honest, there is so much 'wrong' with this query it just isn't fun anymore =/
Some thoughts:
IFNULL() is much more readable than CASE WHEN <field> IS NULL THEN constant ELSE <field> END, especially if turns out to be a sub-query.
AFAIK COUNT(*) will always return 0, even if nothing is found. Thus, there is no need to write an IFNULL() around it
COUNT(field) only counts the non-NULL records for this field, but again, if nothing is found it will return 0, so no need for an IFNULL() around it
You should teach yourself how to JOIN tables as it's (much) better practice than using correlated sub-queries all over the place.
I don't know much about mysql, but it seems to me that you're killing your performance by putting casts and functions around the fields that otherwise seem to have a useful index. I'm pretty sure that due to these constructions the engine simply is not able to use said indexes causing performance to go down the drain. eg. I would try to rewrite
AND DATE_FORMAT(DATEOFCALL,'%Y-%m-%d') >= date(now()) into something like AND DATEOFCALL >= CUR_DATE(), after all, both sides are dates (= numbers)
DATE_FORMAT(DATEOFCALL,'%Y-%m-%d') >= date(now()- interval 1 day) into DATEOFCALL >= date(now()- interval 1 day) for the very same reason
I'm also not sure what time(ag.INSTIME) should do ?!?! Is it true whenever the time is different from 00:00:00 ?
I'm VERY surprised this query actually compiles at all as you seem to GROUP BY on just the skillname, but also fetch quite a lot of other fields from the table (e.g. idleonqueue). From an MSSQL background that should not work.. I guess mysql is different although I do wonder what the result will be like.
Anyway, trying to apply some of the above to your query I end up with below. I doubt it will be 'much faster'; it might be just a bit, but I'd consider it a step forward in your mission to clean it up further...
Good luck!
SELECT (SELECT COUNT(ag.`PKEY`) - COUNT(ag.`ANSWERTIME`)
FROM acdcallinformation ag
WHERE ag.`COMPLETED` = 1
AND answertime is null
AND time(ag.INSTIME)
AND ag.DATEOFCALL >= CURDATE()
AND ag.skillid = info.skillid) AS LostCalls,
COUNT(info.idleonqueue) AS CountCallsACD,
COUNT(info.`ANSWERTIME`) AS acdcallinformation_ANSWERED,
skillinfo.skillname AS acdcallinformation_SKILLIDTEXT,
(SELECT COUNT(pkey)
FROM acdcallinformation age
WHERE age.DATEOFCALL >= CURDATE()
AND age.skillid = info.skillid
AND age.`COMPLETED` = 0
AND age.answertime is null
AND age.SKILLID IN (SELECT SKILLID
FROM callcenterinformation cci
WHERE cci.time > (now() - INTERVAL 5 SECOND)
AND cci.callswaiting > 0)) AS Waiting,
-- count(info.`PKEY`) AS CallsWaiting,
info.`DATEOFCALL` AS acdcallinformation_DATEOFCALL,
info.`FIRSTRINGONQUEUE` AS acdcallinformation_FIRSTRINGONQUEUE,
IFNULL(info.`CONNECTTIME`, time('00:00:00')) AS acdcallinformation_CONNECTTIME,
info.`CALLSTATEBEFOREIDLE` AS acdcallinformation_CALLSTATEBEFOREIDLE,
IFNULL(info.`AGENTRINGTIME`, time('00:00:00')) AS acdcallinformation_AGENTRINGTIME,
info.`IDLEONQUEUE` AS acdcallinformation_IDLEONQUEUE,
info.`DDI` AS acdcallinformation_DDI,
info.`CLIP` AS acdcallinformation_CLIP,
info.`SKILLID` AS acdcallinformation_SKILLID,
info.`ACTIONTYPE` AS acdcallinformation_ACTIONTYPE,
info.`ACTIONDESTINATION` AS acdcallinformation_ACTIONDESTINATION,
info.`COMPLETED` AS acdcallinformation_COMPLETED,
info.`HANDLED` AS acdcallinformation_HANDLED,
info.`CONFIRMED` AS acdcallinformation_CONFIRMED,
(SELECT cal.`AGENTSREADY` AS callcenterinformation_AGENTSREADY
FROM `callcenterinformation` cal
WHERE cal.skillid <> 1
AND cal.skillid = info.skillid
ORDER BY pkey DESC LIMIT 1,1) AS agentsready
FROM `acdcallinformation` info
JOIN `skillinfo`
ON skillinfo.pkey = info.skillid
WHERE info.DATEOFCALL >= (date(now()- interval 1 day ))
GROUP BY skillinfo.skillname ;

top viewed from last week

I want to fetch the videos that top viewed from the last week,
my client has the following table :
CREATE TABLE `videos` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`album` int(10) unsigned NOT NULL DEFAULT '0',
`name` varchar(225) NOT NULL,
`title` varchar(255) NOT NULL DEFAULT '',
`uploading_user` int(8) NOT NULL DEFAULT '2715',
`host` tinyint(1) unsigned NOT NULL DEFAULT '0',
`host_url` varchar(255) NOT NULL DEFAULT '',
`active` tinyint(1) unsigned NOT NULL DEFAULT '0',
`featured` tinyint(1) unsigned NOT NULL DEFAULT '0',
`date_added` date NOT NULL DEFAULT '0000-00-00',
`view` int(125) NOT NULL,
`rating` int(125) NOT NULL,
`rating_count` int(125) NOT NULL,
`category` varchar(225) NOT NULL,
`genre` varchar(225) NOT NULL,
`playlist` varchar(225) NOT NULL,
`video_image` varchar(225) NOT NULL,
`votecount` int(5) DEFAULT NULL,
`banner_image` varchar(255) NOT NULL DEFAULT 'IB_header_solo4.jpg',
`bg_image` varchar(255) NOT NULL DEFAULT 'IB_bck_hd_sect.jpg',
`bg_color` varchar(255) NOT NULL DEFAULT '#000000',
`user_video` int(1) NOT NULL DEFAULT '0',
`description` varchar(1000) DEFAULT NULL,
`country` varchar(30) DEFAULT NULL,
`city` varchar(50) DEFAULT NULL,
`location` varchar(50) DEFAULT NULL,
`reported` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1531 DEFAULT CHARSET=latin1
in this table date_added field for on which date we have added this video,
and i have updated the table on every video view in the view field, means i have the total views of the particular video.
now what i want, how can i fetch the result of top views videos from last week?
can i have to add another date field on which i add the id of the viewed videos?
or any other alternate solution?
If you want to get a list of videos with the number of views in the last week, you need to store views separately. The views column in the table would only give you access to the total number of views but it does not give any indication as to when those views were generated.
I would use a table with video_id, datetime and number of views to store the views. By using a DATETIME column and the requirement that the combination video_id and DATETIME is unique, you can store views down to the second and create more statistics later.
I think it's best you keep a separate table to store who viewed the videos, adding it to this table you will be limited with the number of people you can associate as viewers. Regarding your query. It would be better if you keep a seperate field that stores weekly views.
assuming you had a field called week_views
SELECT required_fields FROM videos ORDER BY week_views DESC
SELECT * (or required fields) FROM videos
WHERE date_added >= CURDATE() - INTERVAL WEEKDAY(CURDATE()) +7 DAY
AND date_added < CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY
ORDER BY view DESC
Something like that should select the videos from last week, Monday to Sunday (not necessarily last 7 days.)