MYSQL: Query to get previous and next video ID? - php

I am developing a video website (PHP - MYSQL), just like youtube, in which I want to provide the functionality of Next video and Previous video. Let's say I am currently on videoId: 234 so Next and Previous video links will point to videoId: 233 and 235 respecively.
My table structure is as follows:
videoId videoName videoURL IsActive
-----------------------------------------------------
1 Love world love-world 1
2 Hello world hellow-world 1
3 World news world-news 0
4 The web the-web 1
5 Google web google-web 1
6 Internet internet 1
IsActive a bool (0,1) type column is basically tells that video is viewable on website or not. If its 0 - notviewable and 1 - viewable
Now there are two type of situations which I though are:
When I am browsing through videoId: 4 then I want to run a query to get the the next and previous video id means 2 and 5 respectively, 3 is not because it is disabled.
Other condition would be When I am browsing through videoId: 1 then query should return only one record which is 2, because there is no previous record, same in the case of last record.
Please tell me how to make query for this?
Thanks

I think you could use something like:
SELECT *
FROM videos AS c
WHERE (VideoId = (SELECT MAX(VideoId) FROM videos WHERE VideoId < c.VideoId AND IsActive = 1)
OR VideoId = (SELECT MIN(VideoId) FROM videos WHERE VideoId > c.VideoId AND IsActive = 1))

I'd use
SELECT * FROM videos WHERE videoId > :id AND IsActive = 1 LIMIT 1
UNION
SELECT * FROM videos WHERE videoId < :id AND IsActive = 1 LIMIT 1

This will get the next one
$stmt = $PDO->prepare("SELECT * FROM vedios WHERE vedio > :id AND IsActive = 1")
$stmt->execute(array("id" => $id));
$all = $stmt->fetchAll(PDO::FETCH_ASSOC);
And change > to < for previous. If count($all) return 0, then you don't have a next/previous video.

Try this. Completely untested, but this will give you a normal row with two additional columns 'nextID' and 'prevID'. If one of them is null, then there isn't one.
SELECT v.*, n.id AS nextID, p.id AS prevID
FROM vedios v
LEFT JOIN (SELECT vn.id FROM vedios vn WHERE vn.id > v.id AND isActive = 1 ORDER BY id ASC LIMIT 1) n
LEFT JOIN (SELECT vp.id FROM vedios vp WHERE vp.id < v.id AND isActive = 1 ORDER BY id DESC LIMIT 1) p
If you have any issues / errors with it, let me know and I'll test it properly.

best query string :
SELECT
(SELECT MAX(`id`) FROM `table` WHERE `id` < `t`.`id`) as `_prev_id`,
(SELECT MIN(`id`) FROM `table` WHERE `id` > `t`.`id`) as `_next_id`
FROM `table` `t`
WHERE `t`.`id` = '1'
LIMIT 1

Related

select query with 2 tables

I have page where people can post comments and page where people can click "follow" on other people profiles (same as LIKE on Facebook)
I would like to have SELECT query that will post all the comments I have, but will order them with the follow way:
first, print the 2 newest comments (they must been posted this week) of the lastest people you click FOLLOW.
second, post the rest of the posted, order them by create-date
(I'm using linux time)
Can you help me with the SQL query?
this is my current SELECT query. it pull all comment by create-date:
SELECT id, userID, text, createDate FROM `comments` AS comment WHERE (comment.refID = 0) AND (comment.pageName = 'yard') AND 1=1 ORDER BY comment.createDate DESC LIMIT 0, 20
"followers" table looks like this:
userID ownerID createDate
1 2 1439019657
1 4 1438940399
"comments" table looks loke this:
id userID pageName refID text createDate
220 1 yard 0 text1 1438030967
227 1 yard 0 text2 1438031704
228 1 yard 0 text3 1438031704
I might've messed up followers' relations. Example data looks incoplete for full context. It shows userID=1 comments for sure, but either no one who follows userID=1 or both 3 and 4 follow him. No idea what refID is doing in comments table. Query shows only a concept anyway - you'll figure out details.
SELECT un.* FROM ((
SELECT 1 as priority, comment.id, comment.userID, comment.text, comment.createDate
FROM `comments` as comment
INNER JOIN `followers` as follower ON follower.userID = comment.userID
WHERE comment.refID = 0
AND comment.pageName = 'yard'
AND ...
ORDER BY follower.createDate DESC LIMIT 2
) UNION DISTINCT (
SELECT 2 as priority, id, userID, text, createDate
FROM `comments` as comment
WHERE comment.refID = 0
AND comment.pageName = 'yard'
)) as un ORDER BY un.priority, un.createDate DESC LIMIT 20

MYSQL sort the next row with the UploadDate when Wilson score interval are equal

I'm working on my photo gallery and I have a filter to sort my media with a Wilson score interval. This score is saved in a field of my table called score
For this query I use the following fields : id, UploadTime, score
The issue I am having is that some scores will be exactly the same if lets say if mulitple picture have only one thumb up. In that case I would like to sort the media by the UploadDate field, make the older picture less relevant.
This is my script to sort out all my picture (keep in mind that the score must me higher than 0 to get in the list)
SELECT *
FROM photos
WHERE status = 0
AND score > 0
ORDER BY score DESC, id DESC
Then for getting the next picture (the next picture is a picture with a lower score or if score is equal output the latest one uploaded). And the $id is the unique id of the current picture
SELECT *
FROM photos p
INNER JOIN
(
SELECT score, id
FROM photos
WHERE id = ".$id."
) p2 ON p.score < p2.score
WHERE p.status = 0 AND p.net_votes > 0
ORDER BY p.score DESC, p.UploadTime DESC
LIMIT 1
I have used up all my ideas on how to do this.
I'm not entirly sure (I might have gotten a > instead of < somewhere). Hopefully this will work
SELECT *
FROM photos
WHERE status = 0
AND net_votes > 0
AND ( score < (SELECT p1.score
FROM photos p1
WHERE p1.id = :id)
OR uploadtime < (SELECT p2.uploadtime
FROM photos p2
WHERE p2.id = :id) )
ORDER BY score DESC,
uploadtime DESC
LIMIT 1

How can I get the nearest rows in mysql?

Lets say I'm trying to build a thumbnail of some gallery (5 thumbnails showing). How can I get my mysql to display 5 thumbnails, the middle thumbnail will be the image blown up, and the two on the left of the middle will be previous images, and the two other images on the right of the middle will be 2 more images after.
EDIT
I know how to easily get 5 thumbnails with something like this
$sqlThumb = mysql_query("SELECT iID,thumbnails,userID FROM images WHERE userID = ".$_SESSION['userID']." ORDER BY iID ASC LIMIT 1,5");
But the thing is, I dont have a consistent id (meaning, there will be deleting and inserting). It is based on the images that the user has.
iID userID
----- --------
1 5
2 4
3 4
4 5
5 5
6 5
10 5
11 5
12 5
So if a user clicks an image which shoes iID number 5, the thumbnail should show like this in order, 1,4,5,6,10.
However, also if a user clicks on thumbnail number 10, the thumbnail should show: 5,6,10,11,12.
Try this
$offset = $current_id-3;
(SELECT * FROM TBL WHERE id < '$current_id' limit '$offset',2 )
union( SELECT * FROM TBL WHERE id = '$current_id')
union (SELECT * FROM TBL WHERE id > '$current_id' limit 2)
I don't know if this works, but the idea is to have an attribute called row_number. You will get the image you want by the id and the two last and the two next by the row number.
SELECT iID,thumbnail FROM image_collection,
(SELECT iID, thumbnail, row_number
FROM
(SELECT iID,thumbnail,
#curRow := #curRow + 1 AS row_number
FROM image
WHERE userID = 5
ORDER BY iID) as image_collection
WHERE s_image.iID = 10) as image_selected
WHERE image_collection.row_number BETWEEN image_selected.row_number - 2 AND image_selected.row_number + 2
I don't tested it because I don't have MySQL running, but I see how to put the row number here: With MySQL, how can I generate a column containing the record index in a table?
Try this one (doesn't include any subtraction):
$id = 5;
$user_id = $_SESSION['userID'];
$sqlThumb = mysql_query("
SELECT iID FROM images WHERE userID = ".$user_id." AND iID = ".$id."
UNION (SELECT iID FROM images WHERE userID = ".$user_id." AND iID < ".$id." ORDER BY iID DESC LIMIT 2)
UNION (SELECT iID FROM images WHERE userID = ".$user_id." AND iID > ".$id." ORDER BY iID ASC LIMIT 2)
ORDER BY iID ASC")

PHP / MySQL Checking data between tables with long query

This is a more detailed question as my previous attempt wasn't clear enough. I'm new to MySQL and have no idea about the best way to do certain things. I'm building a voting application for images and am having trouble with some of the finer points of MySQL
My db
_votes
id
voter_id
image_id
_images
id
file_name
entrant_id
approved
_users
id
...
Basically I need to do the following:
tally up all votes that are approved
return the top 5 with the most votes
check if the user has voted on each of these 5 (return Boolean) from another table
I've tried variations of
SELECT i.id, i.file_name, i.total_votes
FROM _images i WHERE i.approved = 1
CASE WHEN (SELECT count(*) from _votes v WHERE v.image_id = i.id AND v.voter_id = ?) > 0 THEN '1' ELSE '0' END 'hasvoted'
ORDER BY i.total_votes DESC LIMIT ".($page*5).", 5
is that something I should try and do all in one query?
This query was working fine before I tried to add in the 'hasvoted' boolean:
SELECT id, file_name, total_votes FROM _images WHERE approved = 1 ORDER BY total_votes DESC LIMIT ".($page*5).", 5
At the moment I'm also storing the vote count in the _images table and I know this is wrong, but I have no idea about how to tally the votes by image_id and then order them.
Let me give this a shot to see if I understand your question:
SELECT i.*,(SELECT COUNT(*) FROM _votes WHERE i.id = image_id) AS total_votes, (SELECT count(*) from _votes where i.id = image_id and user_id = ?) as voted FROM _images AS i WHERE i.approved = 1

Advanced SQL query. Top 12 from each category (MYSQL)

I have a MYSQL5 database and PHP 5. I need a query for a games websites index page that only selects the first 12 from each category of games. Here is what I have so far.
$db->query("SELECT * FROM `games` WHERE status = 'game_published' AND `featured` = '1' ORDER BY `category`");
The php code then groups games of the same category together and displays them. But yeah it doesn't limit the number of games from each category like I want.
Here is exactly what the structure of the table looks like: i49.tinypic.com/aysoll.png
Here is a blog post which sounds like what I am trying to do: http://www.e-nformation.net/content/view/title/MySQL+Top+N+in+each+group+(group+inner+limit) But I can't make sense of it.
Any help is appreciated.
How about this?
SELECT * FROM (
SELECT
games.*,
#rn := CASE WHEN #category=category THEN #rn + 1 ELSE 1 END AS rn,
#category := category
FROM games, (SELECT #rn := 0, #category := NULL) AS vars
WHERE status = 'game_published' AND featured = '1'
ORDER BY category
) AS T1
WHERE rn <= 12
you could use UNION, if we are not talking about million of types...
pseudoSQL:
(SELECT * FROM table WHERE condition AND category = 'action' ORDER BY id LIMIT 10)
UNION
(SELECT * FROM table WHERE condition AND category = 'action' ORDER BY id LIMIT 10)
UNION
(SELECT * FROM table WHERE condition AND category = 'action' ORDER BY id LIMIT 10)
If you have array of categories in your PHP/ASP, you can generate this union on the fly.
More:
http://dev.mysql.com/doc/refman/5.0/en/union.html
EDIT:
Here's probably most useful resource: http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
Use it well ^^
There may be a more elegant solution, but you can just execute a query for each category. First get a list of categories:
SELECT DISTINCT(category) FROM `games`;
Then take each of the results and query for 12 rows:
SELECT * FROM games WHERE status = 'game_published'
AND `featured` = '1' AND `category` = $category LIMIT 12;
Of course you need to add some kind of ranking row (and order by it) to get the top 12.
Note: There may be a way to do this with a single query, but it escapes me at the moment.
To use the technique from the posts you mention, you need a way to order the games. They're using article date. Then they select the number of older articles for that company, and say there can't be more than three.
If your games table has an auto-increment column called id, you can select the top 10 games per category like:
SELECT *
FROM games g1
WHERE status = 'game_published'
AND featured = '1'
AND 10 >
(
SELECT COUNT(*)
FROM games g2
WHERE g2.status = 'game_published'
AND g2.featured = '1'
AND g1.category = g2.category
AND g2.id > g1.id
)
The where condition says that there can't be more than 10 rows with the same category and a higher ID.

Categories