Right now I'm using UNION to get records from multiple tables, which is fine. But I want to include the author for the specific post.
$run = mysql_query("
SELECT article_id AS id, title, smalldesc, hits, coverpic AS picture, timestamp, member_id AS mid, type FROM articles
UNION
SELECT video_id AS id, titel, smalldesc, hits, ytid AS picture, timestamp, member_id AS mid, type FROM videos
UNION
SELECT picture_id AS id, title, smalldesc, hits, coverpic AS picture, timestamp, member_id AS mid, type FROM pictures ORDER BY timestamp DESC LIMIT ".$postnumbers." OFFSET ".$offset."
") or die(mysql_error());
I want the following select to be a part of the code above:
SELECT member_id, picture, fname, lname FROM members WHERE member_id='mid'
I want to get the member from each post, so I can print out who made the post.
You've got, as you asked, to join the members table to the three part queries of the UNION:
SELECT
a.article_id AS id,
a.title,
a.smalldesc,
a.hits,
a.coverpic AS picture,
a.timestamp,
a.member_id AS mid,
a.type,
m.picture,
m.fname,
m.lname
FROM
articles a
INNER JOIN
members m
ON
a.member_id = m.member_id
UNION
SELECT
v.video_id,
v.titel,
v.smalldesc,
v.hits,
v.ytid AS picture,
v.timestamp,
v.member_id AS mid,
v.type
m2.picture,
m2.fname,
m2.lname
FROM
videos v
INNER JOIN
members m2
ON
v.member_id = m2.member_id
UNION
...
to get this information.
Related
I have a query where I want to fetch columns from two tables (a parent and reference table), as well as select total number of categories of each post on the reference table
articles
id
title
poster
pdate
content
categories
id
name
cats_rel (Relationship table with Foreign Key constraints)
id
pid
cat_id
I want to fetch list of posts with one category id and total number of categories for each post.
I use this to fetch the required data, but it is slow. Is there a better way to get it faster?
SELECT cc.id, title, poster, pdate, content, js.pid, js.sno
FROM articles cc LEFT JOIN
(SELECT pid, cat_id, count(cat_id) as sno FROM cats_rel GROUP BY pid)js
ON js.pid = cc.id WHERE cc.status='approved' ORDER BY cc.id DESC
You don't need a inner query.
SELECT cc.id, title, poster, pdate, content, js.pid, count(js.cat_id) as sno
FROM articles wp
LEFT JOIN cats_rel js ON js.pid = cc.id
WHERE wp.status='approved'
group by cc.id, title, poster, pdate, content, js.pid
ORDER BY cc.id DESC
I would rewrite the query using a correlated subquery
SELECT cc.id, cc.title, cc.poster, cc.pdate, cc.content,
(SELECT COUNT(*)
FROM cats_rel js
WHERE js.pid = cc.id
) as sno
FROM articles cc
WHERE cc.status = 'approved'
ORDER BY cc.id DESC;
(It seems that js.pid is redundant in the select list.)
For this query, you want two indexes: articles(status, id desc) and cats_rel(pid).
Some background:
I'm developing kind of social network.
There is DB with next tables:
users(user_id, user_name, password, etc.)
posts(post_id, user_id, post_text, post_data, etc.)
followings(relationship_id, follower_id, following_id, added_date_time)
likes(like_id, user_id, post_id, added_date_time)
comments(comment_id, user_id, post_id, comment_text, added_date_time)
The question is:
How can I implement query which would fetch information about what my followings(people I follow) have did recently (e.g. someone liked/commented something) and order this array of info by date_time?
Can I make it using one query? Or I'll have to make multiple queries and handle all this stuff in PHP by myself?
What is the best approach?
You can normalize the output in a select union like this one
SELECT t.type, t.user_id, u.user_name, t.type_id, t.post_id, t.text, t.added_date_time
FROM (
SELECT 'posts' as type, p.user_id, p.post_id as type_id, p.post_id, post_text as text, p.added_date_time
FROM posts p
JOIN followings f ON (f.following_id = p.user_id)
WHERE f.follower_id = #user
UNION
SELECT 'comments' as type, c.user_id, c.comment_id as type_id, c.post_id, comment_text as text, c.added_date_time
FROM comments c
JOIN followings f ON (f.following.id = c.user_id)
WHERE f.follower_id = #user
UNION
SELECT 'likes' as type, l.user_id, l.like_id as type_id, l.post_id, post_text as text, l.added_date_time
FROM likes l
JOIN followings f ON (f.following.id = c.user_id)
JOIN posts p ON (l.post_id = p.post_id)
WHERE f.follower_id = #user
) as t
JOIN users u ON (t.user_id = u.user_id)
ORDER BY added_date_time DESC;
So you can get all the data in only one query.
I hope it works fine for you.
You have to seperate at least the queries for likes and comments, since the result set is different.
Otherwise your query would look e.g. like:
SELECT comment_id,comment_text,added_date_time FROM comments WHERE user_id IN (SELECT following_id FROM followings WHERE follower_id={{USER_ID_FROM_USER}}) ORDER BY added_date_time
This will get you the comments from people which are followed by {{USER_ID_FROM_USER}} ordered by date.
I`m trying to extract the activity of a user with a single query. I need to do it with one single query so I can use zend paginator.
I have 5 tables: users, replies, threads, wiki_articles and wiki_article_revisions. Each table has 2 common columns created_by and created_on.
I've tried using left join but I think what it returns is not correct and I'm unable to order all activity by created_on
Here is the join I've tried:
SELECT * FROM `users` u
LEFT join `replies` r ON u.id = r.created_by
LEFT join `threads` t ON u.id = t.created_by
LEFT join `wiki_articles` wa ON u.id = wa.created_by
LEFT join `wiki_article_revisions` war ON u.id = war.created_by
WHERE (u.`name` = 'CGeorges')
My thought process was wrong. I should have used UNION for this, like:
(SELECT id, name, created_on FROM users WHERE id = 1)
UNION
(SELECT id, name, created_on FROM threads WHERE created_by = 1)
UNION
(SELECT id, content, created_on FROM replies WHERE created_by = 1)
UNION
(SELECT id, title, created_on FROM wiki_articles WHERE created_by = 1)
ORDER by created_on DESC
I have a query that I am using to join two tables (posts, relations) to return posts from users you are following (r.status= 1) or friends (r.status= 2) with. But then also omitting the posts where the post privacy is private (p.privacy= 2) and the current relationship (r.status= 1).
Here is my query:
$user_id= 1;
$posts_query= "
SELECT DISTINCT post_id, user_id, story, photo, link, collection_id, privacy, date, type
FROM posts p
JOIN relations r ON p.user_id = r.recipient
AND (r.sender = '".$user_id."')
AND NOT (r.status = 1 AND p.privacy = 2)
ORDER BY p.post_id DESC;
";
Now the only problem with this query is that It omits your own personal posts.
The query for that would be:
$your_posts_query= "SELECT * FROM posts WHERE user_id= '".$user_id."' ORDER BY p.post_id
DESC";
Now, This doesn't allow me aggregate all of the posts together. Yours, and the ones from your friends and the people you are following.
How can I make it so that my first query also incorporates what my second query does?
$user_id= 1;
$posts_query= "
SELECT DISTINCT post_id, user_id, story, photo, link, collection_id, privacy, date, type
FROM posts p
JOIN relations r ON p.user_id = r.recipient
AND (r.sender = '".$user_id."' OR p.user_id= '".$user_id."')
AND NOT (r.status = 1 AND p.privacy = 2)
ORDER BY p.post_id DESC;
";
Combine the two together to get as one result set
$posts_query= "
SELECT post_id, user_id, story, photo, link, collection_id, privacy, date, type
FROM posts WHERE user_id= '".$user_id."'
union
SELECT DISTINCT post_id, user_id, story, photo, link, collection_id, privacy, date, type
FROM posts p
JOIN relations r ON p.user_id = r.recipient
AND (r.sender = '".$user_id."')
AND NOT (r.status = 1 AND p.privacy = 2)
ORDER BY p.post_id DESC;
";
I am struggling with a MYSQL query - I have 2 tables :
Table 1 (info) containing UID, first_name, last_name.
Table 2 (card) containing UID, pic .
What I am trying to do is get all results into an array:
WHERE UID IN '$ids' AND LEFT(last_name,1) = '$letter' ORDER BY last_name, first_name ASC
I figured an INNER JOIN so my current code is:
("SELECT UID, first_name, last_name, pic FROM
(SELECT info.first_name,info.last_name,card.pic FROM info
INNER JOIN card ON info.UID=card.UID)
WHERE LEFT(last_name,1) = '$letter' ORDER BY last_name, first_name ASC")
This is producing the following error though:
'Every derived table must have it's own alias'.
Am I going about this the right way with inner join, and how do I give the derived table an alias? Thanks in advance!
select b.UID, g.first_name, g.last_name, b.pic
from user_data.general_info g
inner join user_data.Bcards b on g.UID = b.UID
where LEFT(g.last_name, 1) = '$letter'
order by g.last_name, g.first_name asc
The inner query should be named.
SELECT users.UID, users.first_name, users.last_name, users.pic FROM
(SELECT info.first_name,info.last_name,card.pic FROM user_data.general_info
INNER JOIN user_data.Bcards ON general_info.UID=Bcards.UID) users
WHERE LEFT(users.last_name,1) = '$letter' ORDER BY users.last_name, users.first_name ASC