Inner join with 3 tables - php

I'm working with PHP and PDO, and I need to recolect information joining 3 tables:
photos
albums
album_photos
The table have the following structure:
photos:
photo_id (int)
path (varchar)
nick (varchar)
date (timestamp)
albums
album_id (int)
album_name (varchar)
nick (varchar)
date (timestamp)
album_photos
album_id (int)
photo_id (int)
nick (varchar)
date (timestamp)
So, I want to show all the albums with a max of 5 photos for each one, where the user nick is 'owner'.
To be shown as follows:
album_name_1:
[photo_1]
[photo_2]
[photo_3]
[photo_4]
[photo_5]
album_name_2:
[photo_1]
[photo_2]
[photo_3]
[photo_4]
[photo_5]
I only know that something like this can be made with INNER JOIN, but I can't found how I can make it with 3 tables.
There examples or other help that I can get to do this?

SELECT a.*, c.date
FROM Album a
INNER JOIN Album_Photo b
ON a.Album_ID = b.Album_ID
INNER JOIN Photo c
ON b.Photo_ID = c.Photo_ID
WHERE c.Nick = 'owner' AND
(
SELECT COUNT(*)
FROM album_photo d
WHERE b.album_id = d.album_id AND
d.nick = 'owner' AND
b.date >= d.date
) <= 2 // <<== change this value to 5
SQLFiddle Demo

I think this can be resolved using Stored Procedures. Using variables and loops, you can retrieve the records you desire. Getting only a maximum of 5 records from an album is quite challenging when you only use the basic SQL commands. Sometimes, you cannot derive the right records. I suggest you use Stored Proc. :)

Try like
"SELECT albums.*,photos.id,photos.path,photo_date as Pht_date
FROM albums
JOIN album_photos
ON album_photos.album_id = albums.album_id
JOIN photos
ON photos.photos_id = album_photos_id
"
But you cont give individual limit for photos where it involved in "JOIN" orelse you need to give individually like
$album_ids = "SELECT album_id FROM albums";
then for the photos you need to write query liks
"SELECT photos.* FROM photos
WHERE album_photos.album_id in (".$album_ids.") AND album_photos.nick = 'owner'
JOIN album_photos
ON album_photos.photo_id = photos.photos_id
LIMIT 0,10
"

Related

How to count records in MySQL and merge results in PHP

I have a table which stores clients like this:
id name
-- ----
1 John
2 Jane
...
I also have another table which stores links created by clients:
id client_id link created
-- --------- ---- -----------
1 1 ... 2015-02-01
2 1 ... 2015-02-26
3 1 ... 2015-03-01
4 2 ... 2015-03-01
5 2 ... 2015-03-02
6 2 ... 2015-03-02
I need to find how many links a client has created today, this month and during all the time. I also need their name in the result, so I'll be able to craete a HTML table to display the statistics. I thought I can code as less as possible like this:
$today = $this->db->query("SELECT COUNT(*) as today, c.id as client_id, c.name FROM `links` l JOIN `clients` c ON l.client_id = c.id WHERE DATE(l.created) = CURDATE() GROUP BY c.id");
$this_month = $this->db->query("SELECT COUNT(*) as this_month, c.id as client_id, c.name FROM `links` l JOIN `clients` c ON l.client_id = c.id WHERE YEAR(l.created) = YEAR(NOW()) AND MONTH(l.created) = MONTH(NOW()) GROUP BY c.id");
$yet = $this->db->query("SELECT COUNT(*) as yet, c.id as client_id, c.name FROM `links` l JOIN `clients` c ON l.client_id = c.id WHERE GROUP BY c.id");
And then merge them in PHP as I asked HERE before, like this:
$result = array_replace_recursive($today, $this_month, $yet);
So I'll be able to loop into the result and print my HTML table.
But there are logical problems here. Everything works fine, but the result in a month is a wrong number, forexample the whole created links of one person is 1 but it shows 4 in the monthly counter! I also tried to use RIGHT JOIN in SQL query to get all clients, so array_replace_recursive in PHP could work fine as I think it doesn't work properly at the moment, but no success and got wrong results again.
Can anyone show me a way to make the job done?
This query should do it for today
$query_today="
SELECT name, id AS user_id, (
SELECT COUNT( * )
FROM links
WHERE client_id = user_id AND created = '2015-03-02'
) AS alllinks
FROM clients"
adjust the WHERE clause in the subquery for months and all
$query_month="
SELECT name, id AS user_id, (
SELECT COUNT( * )
FROM links
WHERE client_id = user_id AND created like '2015-03%'
) AS alllinks
FROM clients"
$query_all="
SELECT name, id AS user_id, (
SELECT COUNT( * )
FROM links
WHERE client_id = user_id
) AS alllinks
FROM clients"

How to get the select the sum of a column JOINing with another table where elementxof table1 = elementx of table2?[special case]

I have two tables named videos and rating.
The first table
videos
uploader video_id
james ac0255
james ue2145
isabell qw2378
The second table:
rating
video_id score
ac0255 4
qw2378 2
ue2145 6
I want to store in variable x the sum of the score of all the videos uploaded by james.
Can anyone suggest an SQL query for it?
Try with this:
SELECT SUM(rating.score)
FROM videos
INNER JOIN rating
ON videos.uploader = rating.video_id
WHERE videos.uploader = 'james';
A simple join will do.
SELECT sum(r.score)
FROM videos v
JOIN rating r ON (v.video_id = r.video_id)
WHERE v.uploader = 'james';
In order to get the sum of score for James , you need to use JOINS and SUM function of mysql
SELECT SUM(Rating.score)
FROM videos as Videos
INNER JOIN rating AS Rating
ON Videos.uploader = Rating.video_id
WHERE Videos.uploader = 'james';

Selecting an id with inner join

I'm trying to construct an user profile, so I'm showing all her likes from the database.
But I want to look if the user that have the active session has liked some of the user profile likes.
So, the table name is loves and the structure is:
photo_id (int)
nick (varchar)
date (timestamp)
photos table structure:
photo_id (int)
path (varchar)
title (varchar)
category (varchar)
nick (varchar)
date (timestamp)
This is how I'm traying to do the query:
SELECT photos.photo_id
FROM photos
INNER JOIN loves ON loves.nick = 'userProfileName'
WHERE loves.nick = 'userWithActiveSession'
AND photos.photo_id = loves.photo_id
ORDER BY loves.photo_id DESC
LIMIT 100
This query should return all photo ID's that the user with active session have liked with the liked photos from the profile requested user.
EXAMPLE
loves table:
nick photo_id
userProfile 26
userProfile 1000
userProfile 27
userProfile 520
userSession 26
userSession 680
userSession 1000
So the query should return only two photos_id (1000 and 26), because both users has liked the same photo_id.
Is there any way to modify this code to do what I want?
So you want all the photos owned by X (photos.nick = X) and liked by Y?
SELECT photos.photo_id FROM photos INNER JOIN loves
ON loves.photo_id = photos.photo_id
WHERE loves.nick = Y AND photos.nick = X
ORDER BY photos.photo_id DESC LIMIT 100
If you want photos liked by both X and Y then you need to join loves to itself, matching the photo_ids from the two copies of the table to each other, and conditioning that one table's nick matches X and the other's matches Y. (See comments)
you could get the photo_id without join like this:
SELECT photo_id
FROM loves
WHERE photo_id in (select photo_id from loves where nick = "userProfile" )
AND photo_id in (select photo_id from loves where nick = "userSession" )
GROUP BY photo_id
ORDER BY loves.photo_id DESC
LIMIT 100
DEMO HERE
That part looks weird:
INNER JOIN loves ON loves.nick = 'userProfileName'
shouldn't it be (assuming there is a nick field on photos table):
INNER JOIN loves ON loves.nick = photos.nick
or I didn't get something here?

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

php MySql QUERY for Friends relations Table help

EDIT by:lawrence.
I got the right query now
select *
from users, friends
where (users.id=friends.user_id1 and friends.user_id2=$profileID) or (users.id=friends.user_id2 and friends.user_id1=$profileID)
Question answered
I need some help joining results from my friends and users table
This is what my friends table look like
id user_id1 user_id2
1   | 2         | 3
1   | 2         | 4
1   | 2         | 5
1   | 6         | 2
Users table
id name
2 |  sarah
3 |  emma
4 |  lawrence
5 |  cynthia
6 |  suzie
I could easily just have two rows for each relation and do a simple query.
But i prefer having one row per relation,
So lets assume that we are watching page member.php?profile=2
and there is a list of friends, what does the query look like.
This works fine if i have two rows per relation but i dont want that....
SELECT * FROM friends, users WHERE friends.user_id1 = $profileID AND friends.user_id2 = users.id ORDER BY friends.id DESC LIMIT 16
Do you get me? something along like
SELECT * FROM friends,users WHERE friends.user_id1 = $profileID AND ALSO WHERE friends.user_id2 = $profileID AND THEN GET FROM users WHERE users.id = friends.user_id1 AND ALSO WHERE users.id = friends.user_id2
I hope I made myself clear
I'm not sure i understand your question but won't this do?
SELECT * FROM friends, users where friends.user_id1 = $profileID or friends.userid2 = $profileID and users.id = friends.user_id1 or users.id = friends.user_id2
You want a left join (using the LEFT JOIN operator), not a cartesian join (using the FROM table1, table2 syntax).
http://www.w3schools.com/sql/sql_join_left.asp
Tip: With your cross-reference table instead of having an id column you can create a compound key.

Categories