Database Scheme:
http://pastebin.com/aPXk1rMf
I'm want to select "post owner's uName" and "comment owner's uName" from "comments" table (i.e. I think I need cOwnerID>uName and pID>uID>uName) so that I can log some activities right after a comment is posted.
I tried to use MySQL joins in order to achieve that but I couldn't; so here's what I tried in vain.
$result = dbquery("INSERT INTO comments VALUES ('','$pID','$ownerID','$cmnt')"); // inserting a comment
$lastID = mysql_insert_id();
$res = dbquery("SELECT
users.username AS username
FROM `comments`
LEFT JOIN `users` on comments.cOwnerID = users.uID
WHERE (cID='$lastID')");
I think you have to use aliases for table users, because, actually, you will have two joins on this table : one for the post author and another for the comment's author.
Try something like this :
SELECT
commentAuthor.username AS commentauthor_username,
postAuthor.username AS postauthor_username
FROM `comments`
LEFT JOIN `users` AS commentAuthor on comments.cOwnerID = commentAuthor.uID
LEFT JOIN `posts` on posts.pId = comments.pID
LEFT JOIN `users` AS postAuthor on posts.uID = postAuthor.uID
WHERE (cID='$lastID')
SELECT users1.username, users2.username FROM Posts p
WHERE p.pID="$POST_OF_INTEREST"
LEFT JOIN users users1 ON users1.uID=p.uID
LEFT OUTER JOIN comments ON comments.pID=p.pID
LEFT OUTER JOIN users users2 ON users2.uID=comments.cOwnerID
Given a particular post ID, this will get the username of the person who posted and the username of each person who commented on that post (one row per comment).
SELECT Users.uName AS UserNamePost
, UserComment.uName AS UserNameComment
FROM Users
INNER JOIN Posts
ON Posts.uID = Users.uID;
INNER JOIN Comments
ON Comments.pID = Posts.pID ;
INNER JOIN Users AS UserComment
ON Comments.cOwnerID = UserComment.uID ;
This will aim to have the user that has posted the post and then join the user for all comments for the post
"SELECT
users.username AS username,
comments.cOwnerID AS commentOwner,
users.uID AS userID
FROM
comments
LEFT JOIN
users
ON
commentOwner = userID
WHERE
commentOwner = '{$lastID}'";
Related
This query is for pulling down comments and replies if you can imagine a comment thread. The problem is that I needed to include a right join to include comments(These have null column values in reply columns). The problem is that it is pulling down all of the comment rows as you can see from this picture. Why is my filters for pageId, classId, albumId not correctly filtering?
SELECT rp.votes, cmts.pageId, cmts.content_element_id, rp.userId as replyUserId, (select users.firstName from users where users.guid = rp.userId) as replyFirstName,
(select users.lastName from users where users.guid = rp.userId) as replyLastName, rp.originalCommentId as replyOriginalCommentId,
rp.parentCommentId as replyParentCommentId, rp.commentId as replyCommentId, rp.text as replyText, rp.createdAt as replyCreatedAt,
rp.updatedAt as replyUpdatedAt, rp.status as replyStatus, cmts.classId as classId, cmts.albumId as albumId,
cmts.text as OriginalCommentText, cmts.status as CommentStatus, cmts.commentId as commentOriginalId,
cmts.createdAt as CommentCreatedAt, cmts.updatedAt as CommentUpdatedAt, cmts.status as cmtsStatus, cmts.userId as cmtsUserId, (select users.firstName from users where users.guid = cmts.userId) as commentFirstName, (select users.lastName from users where users.guid = cmts.userId) as commentLastName
FROM replies as rp
RIGHT JOIN comments as cmts ON rp.pageId = '36365094-0f52-49e3-bc0e-037edcca574b'
AND cmts.classId = '207'
AND cmts.albumId = '49152e6b-ca80-4889-a65e-4e6fd1dcc367'
AND rp.originalCommentId = cmts.commentId
ORDER BY cmts.createdAt
http://i59.tinypic.com/257q6wg.jpg
I cannot do an inner join, because it wont return the nulled values as seen from the picture.
#Gordon - I think I needed an extra and in there, like this: I'm double checking it now.
RIGHT JOIN comments cmts ON rp.pageId = '36365094-0f52-49e3-bc0e-037edcca574b'
AND rp.originalCommentId = cmts.commentId
WHERE cmts.classId = '207' AND cmts.albumId = '49152e6b-ca80-4889-a65e-4e6fd1dcc367' AND cmts.pageId = '36365094-0f52-49e3-bc0e-037edcca574b'
ORDER BY cmts.createdAt
You are filtering on the second table in the right join in the on clause. So, this does nothing. Add a where clause:
where cmts.classId = '207'AND cmts.albumId = '49152e6b-ca80-4889-a65e-4e6fd1dcc367'
to do the filtering.
A right join keeps all the rows in the second table, regardless of whether the on clause evaluates to "true", "false", or NULL. So, any filter on the second table is ignored.
(Note that for a left join, the same thing applies to the first table.)
EDIT:
The from clause would turn into:
FROM replies rp RIGHT JOIN
comments cmts
ON rp.pageId = '36365094-0f52-49e3-bc0e-037edcca574b' AND
rp.originalCommentId = cmts.commentId
WHERE cmts.classId = '207' AND
cmts.albumId = '49152e6b-ca80-4889-a65e-4e6fd1dcc367'
i have problem in database in my project :
i want to get column "title" from "node" table, the second table "txn" and ther is no relation between tables. the new relation is "vid" from "node" when = the "tid" from "txn" get the title
the condition is i want to get the "title" when the "vid" = "tid
this the existing Join
can i make a JOIN between "node" and "txn" ??
or can i make JOIN between 3 tables?
$query = "SELECT userpoints_txn.description, userpoints_txn.points, userpoints_txn.operation, userpoints_txn.time_stamp, users.name, users.uid, fb_user.uid, fb_user.fbu FROM userpoints_txn
JOIN users ON users.uid = userpoints_txn.uid
JOIN fb_user ON users.uid = fb_user.uid
WHERE `entity_id` = ".$nid." ORDER BY userpoints_txn.time_stamp DESC"
You can left join the three table like this :
SELECT userpoints_txn.description, userpoints_txn.points, userpoints_txn.operation, userpoints_txn.time_stamp, users.name, users.uid, fb_user.uid, fb_user.fbu
FROM userpoints_txn
JOIN users ON users.uid = userpoints_txn.uid
JOIN fb_user ON users.uid = fb_user.uid
JOIN node ON node.vid=userpoints_txn.tid
WHERE userpoints_txn.entity_id= '".$nid."' ORDER BY userpoints_txn.time_stamp DESC
I am making a user status list of the following format "A like B's XXX". A and B are both registered users and have firstname and lastname and user id. How to join the status table with the user table twice to get the names of the two users? Thank you.
SELECT "SQACTION"."TIMECREATED",
"SQWORDLIST".*,
"SUBJECT"."FIRSTNAME" subject_fn,
"SUBJECT"."LASTNAME" subject_ln,
author.firstname author_fn,
author.lastname author_ln
FROM "SQACTION"
INNER JOIN "SQWORDLIST"
ON SQACTION.ACTION = SQWORDLIST.GUID
INNER JOIN "SQUSER" SUBJECT
ON SQACTION.SUBJECT = SUBJECT.GUID
LEFT JOIN SQDOCUMENT
ON SQACTION.ENTITY = SQDOCUMENT.GUID
LEFT JOIN SQUSER AUTHOR
ON SQDOCUMENT.AUTHORID = AUTHOR.GUID
WHERE (SUBJECT.GUID = 'B4D3BF632C0C4DB3AB01C8B284069D8F')
OR (SUBJECT.GUID IN ('67882AF3FA3C4254AF9A12CA0B0AB6E4',
'6A4B52FE233444838AACFE2AFFE4D38F',
'8CA3FB9061FF4710B51F1E398D3D1917'))
ORDER BY "TIMECREATED" DESC
This is what I have tried. Thank you.
You need to include the table name twice in the FROM clause, and use an alias so you can specify which fields from each instance of the table are used in the ON statement. You didn't provide enough details in your question to give an exact example, so here is something more general.
UserTable, with ID & Name
RegTable, with UserID, and SponsorID
select ut1.name as [User],
ut2.name as [Sponsor]
from UserTable ut1
inner join RegTable rt on ut1.id = rt.userid
inner join UserTable ut2 on rt.sponsorid = ut2.id
do you mean something like, status have two field links to user table?
select user_a.first_name as user_a_first_name, user_b.first_name as user_b_first_name, status.status_name
from status
left join users as user_a on user_a.id = status.user_from_id
left join users as user_b on user_b.id = status.user_to_id
I have 3 tables - posts, friendships, and likes -- the important fields described below.
posts: id, user_id, title
friendships: requester_id, accepter_id, is_confirmed
likes: post_id, user_id
I have a method called get_relevant_posts() which should return posts that either I've written, my confirmed friends have written, or my confirmed friends have liked. I've already implemented this in SQLAlchemy, but there's a bug in my query because it only works if the friendships table is not empty (doesnt matter whats in it, just cant be empty). If it is empty, nothing gets returned (improper join?).
This is not a big issue as the friendships table will have something in it 99.99% of the time. But I still want to take a step back and write this in plain SQL -- I just can't seem to wrap my head around it.
SQLALCHEMY CODE
Friendship1 = aliased(Friendship)
Friendship2 = aliased(Friendship)
Friendship3 = aliased(Friendship)
Friendship4 = aliased(Friendship)
return (DBSession.query(Post)
.outerjoin(Friendship1, Post.user_id==Friendship1.accepter_id)
.outerjoin(Friendship2, Post.user_id==Friendship2.requester_id)
.outerjoin(Like, Post.id==Like.post_id)
.filter(or_(
# My post
self.id==Post.user_id,
# My friends post, where I'm the requester of the friendship
and_(self.id==Friendship1.requester_id,
Friendship1.is_confirmed==True),
# My friends post, where I'm the accepter of the friendship
and_(self.id==Friendship2.accepter_id,
Friendship2.is_confirmed==True),
# Somebodies post, which my friends found interesting
and_(self.id==Friendship3.requester_id,
Friendship3.is_confirmed==True,
Like.user_id==Friendship3.accepter_id),
and_(self.id==Friendship4.accepter_id,
Friendship4.is_confirmed==True,
Like.user_id==Friendship4.requester_id)))
.order_by(Post.created_at.desc())
.limit(limit)
.offset(offset)
.all())
PRODUCES THIS
SELECT posts.title AS posts_title
FROM friendships AS friendships_1, friendships AS friendships_2, posts LEFT OUTER JOIN friendships AS friendships_3 ON posts.user_id = friendships_3.accepter_id LEFT OUTER JOIN friendships AS friendships_4 ON posts.user_id = friendships_4.requester_id LEFT OUTER JOIN likes ON posts.id = likes.post_id LEFT OUTER JOIN users AS users_1 ON users_1.id = posts.user_id
WHERE (posts.user_id = %s OR friendships_3.requester_id = %s AND friendships_3.is_confirmed = %s OR friendships_4.accepter_id = %s AND friendships_4.is_confirmed = %s OR friendships_1.requester_id = %s AND friendships_1.is_confirmed = %s AND likes.user_id = friendships_1.accepter_id OR friendships_2.accepter_id = %s AND friendships_2.is_confirmed = %s AND likes.user_id = friendships_2.requester_id) ORDER BY posts.created_at DESC
LIMIT %s
Assuming we have MS SQL 2005
With rels
(
Select f.requesterId as target_id
From friendships f
Where is_confirmed = 1 and f.accepter_id='Your Id'
Union
Select 'Your id'
)
Select p.*
From posts p
left join rel r on r.target_id = p.user_id -- this will be null on for non-target users
left join likes l on p.post_id=l.post_id -- here we will pick likes
left join rel r1 on r1.target_id=l.user_id
where coalesce(r1.target_id, r2.target_id) is not null -- telling sql to pick posts we are interested in
or replace CTE rel with sub-query.
Figured it out in a different way. Doing a subquery with an IN clause to check if any users who like the post are part of my confirmed friends list. The other parts are pretty straigh forward (checking if either I wrote it or a friend wrote it).
Doing a bit of investigation and writing a query against a logs db.
I've joined a number of tables to bring back the data that I need, but i'd like to clean it up a bit.
The query returns all the users and which features they have enabled on their account.
Here is what i'm trying to do to clean it up:
Their is a column called 'actions' which has two states, 'added' and 'removed'
If a user feature has an action of 'removed' then I want to not show any of the rows for the same feature for that user which are also marked as 'added'
Is this possible?!
Here is what I have so far:
select users.id as site_id, users.company_name, feature_log.featurecode, feature.minimum_account as feature_type, users.account_type as site_type, account_types.name as account, feature_log.action, feature_log.time
from users
inner join
feature_log
on users.id = feature_log.siteid
inner join
feature
on feature_log.featurecode = feature.featurecode
inner join account_types
on users.account_type_INC = account_types.id
where feature.minimum_account != 0
AND feature.minimum_account > users.account_type
AND users.status = 'Y'
ORDER BY feature_log.time DESC
Thanks for any support!
So, in order to "mute" all the features, that have been "removed" at any point in time for a given user, you can add a (left) join on the following subquery:
SELECT DISTINCT users.id as siteid, feature_log.featurecode, TRUE as mute_feature
FROM users
INNER JOIN feature_log ON (users.id = feature_log.siteid)
WHERE action = 'removed'
This will be the list of features that a given user disabled at some point in time. Then in your query's WHERE clause, you'd add a filter like so:
AND NOT IFNULL(mute_feature, FALSE)
Essentially, that'd bring your whole query to be:
select users.id as site_id, users.company_name, feature_log.featurecode, feature.minimum_account as feature_type, users.account_type as site_type, account_types.name as account, feature_log.action, feature_log.time
from users
inner join
feature_log
on users.id = feature_log.siteid
left join (
SELECT DISTINCT users.id as siteid, feature_log.featurecode, TRUE as mute_feature
FROM users
INNER JOIN feature_log ON (users.id = feature_log.siteid)
WHERE action = 'removed'
) as muted_features ON (feature_log.siteid = muted_features.siteid AND feature_log.featurecode = muted_features.featurecode)
inner join
feature
on feature_log.featurecode = feature.featurecode
inner join account_types
on users.account_type_INC = account_types.id
where feature.minimum_account != 0
AND feature.minimum_account > users.account_type
AND users.status = 'Y'
AND NOT IFNULL(mute_feature, FALSE)
ORDER BY feature_log.time DESC