Problems with joining two tables in SQL - sql

I have two tables. user(user_id, username, password, age) and comment(comment_id, comment, user_id(foreign key)).
I'm trying to get username from user, using the user_id provided in comment.
My query looks like this:
$sql = "SELECT username FROM user WHERE user_id = (SELECT user_id FROM comments)";
I'm getting null. Is my brain working poorly or is it something else I messed up?
I just want to display all comments after each other, with the username before it.

Use IN instead of "=" .
SELECT username FROM user WHERE user_id IN (SELECT user_id FROM comments);
OR you can use a proper join, something like:
SELECT username FROM user,comments WHERE user.user_id = comments.user_id

That's not a join - a join would be:
$sql = "SELECT username FROM user u JOIN comments c ON u.user_id = c.user_id";
When you use a subquery with =, the subquery must return one value. To show all related records in a related table, use JOIN instead.

Related

Query the fields attached to an entity in SQL drupal database

Users
Screenshot users table
field_data_field_user_first_name
screenshot fields table
What query should I use to get a table like this:
Uid Email First name
1 123#123.com example
I have tried without luck:
SELECT * FROM users
LEFT JOIN field_data_field_user_first_name
ON users.uid = ield_data_field_user_first_name.entity_id
You will get same result as mentioned above by using this query
SELECT users.uid as Uid,users.mail as Email,field_data_field_user_first_name.field_user_first_name_value as FirstName FROM users
LEFT JOIN field_data_field_user_first_name
ON users.uid = ield_data_field_user_first_name.entity_id;

SQL - Select ids that appear at least once in other table

I'm trying to get a list of Users that appear at least once in OtherTable. The following is my very inefficient HQL query using Grails. In general, there will only be at most a few hundred users that will be run in the query but potentially a million references to those users in OtherTable.
List<User> users = User.executeQuery("select user " +
"from User as user where user.id = any(" +
"select otherTable.user.id from OtherTable as otherTable)")
How can I make this query more efficient?
This SQL might be more effcient,
select distinct u.id from user as u
inner join other_table ot
on u.id = ot.id
Here is an HQL,
select distinct user
from User as user
inner join user.otherTable as ot
Using Criteria API
User.createCriteria().listDistinct {
createAlias("otherTable","ot")
eq('id','ot.id')
}
Both the above would require proper mapping of your domain classes. In case, you don't have that, OtherTable, mapped in User. Try this,
select distinct user from User user, OtherTable ot
where user.id = ot.user_id
You may have noticed that we're avoiding full table scans here, completely; and it's a single query -- unlike the one you posted, which uses a subquery. Joining both entities/tables with id should be more efficient -- assuming id columns are indexed.
Try the following query:
List<User> users = User.executeQuery("select user " +
"from User as user where" +
"user.id in (select distinct otherTable.user.id from OtherTable as otherTable)")
Hope it will help!

Select a user by their username and then select data from another table using their UID

Sorry if that title is a bit convoluted... I'm spoiled by an ORM usually and my raw SQL skills are really poor, apparently.
I'm writing an application that links to a vBulletin forum. Users authenticate with their forum username, and the query for that is simple (selecting by username from the users table). The next half of it is more complex. There's also a subscriptions table that has a timestamp in it, but the primary key for these is a user id, not a username.
This is what I've worked out so far:
SELECT
forum.user.userid,
forum.user.usergroupid,
forum.user.password,
forum.user.salt,
forum.user.pmunread,
forum.subscriptionlog.expirydate
FROM
forum.user
JOIN forum.subscriptionlog
WHERE
forum.user.username LIKE 'SomeUSER'
Unfortunately this returns the entirety of the subscriptionlog table, which makes sense because there's no username field in it. Is it possible to grab the subscriptionlog row using the userid I get from forum.user.userid, or does this need to be split into two queries?
Thanks!
The issue is that you are blindly joining the two tables. You need to specify what column they are related by.
I think you want something like:
SELECT * FROM user u
INNER JOIN subscriptionlog sl ON u.id = sl.userid
WHERE u.username LIKE 'SomeUSER'
select * from user u JOIN subscriptions s ON u.id = s.id where u.username = 'someuser'
The bit in bold is what you want to add, it combines the 2 tables into one that you return results from.
try this
SELECT
forum.user.userid,
forum.user.usergroupid,
forum.user.password,
forum.user.salt,
forum.user.pmunread,
forum.subscriptionlog.expirydate
FROM
forum.user
INNER JOIN forum.subscriptionlog
ON forum.subscriptionlog.userid = forum.user.userid
WHERE
forum.user.username LIKE 'SomeUSER'

Oracle SELECT WHERE value exists or doesn't exist

I have 3 tables; CASES, USERS and USER_META. For this issue you need to know that the USER_META table has 3 columns; user_id, meta_key and meta_value
Each user is associated with many CASES and each USER is associated with many USER_META
My current query is like this
SELECT CASES.*, USERS.*, USER_META.*
FROM CASES
JOIN USERS ON USERS."user_id" = CASES."user_id"
JOIN USER_META ON USER_META_"user_id" = USERS."user_id"
The problem with this approach is that each USER has A LOT of USER_META so my result set has too many rows. How can I rewrite this query so that I can select only the USER_META where the USER_META."meta_key" is equal to a certain value yet still get the result if they do not have this USER_META."meta_key" set yet
For example:
SELECT CASES.*, USERS.*, USER_META.*
FROM CASES
JOIN USERS ON USERS."user_id" = CASES."user_id"
JOIN USER_META ON USER_META_"user_id" = USERS."user_id"
WHERE USER_META."meta_key" = 'my_key'
This would work great but not all users have a value of "my_key" in the "meta_key" column and we still need to view their CASE. For users that do not have the "meta_key" the result should just return the CASE and USER columns.
How can I rewrite this query so it gets the result for both users with this meta_key and without?
Thanks, I hope this makes sense.
I would use a LEFT JOIN
SELECT CASES.*, USERS.*, USER_META.*
FROM CASES
JOIN USERS ON USERS."user_id" = CASES."user_id"
LEFT JOIN USER_META ON USER_META."user_id" = USERS."user_id" AND USER_META."meta_key" = ?
you need to use OUTER JOIN with the table that may have no results. In Oracle, use (+) near to the field name of the join sentence with this table. This link may help you: http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries006.htm

MySQL: Join two tables

I'm having problems with design correct SQL query. I'm tired like a hell today, been working over 12 horus (deadline soon) and cannot find issue...
Tables:
buddies | userid | buddyid
users | id | username
Now, what I'd like to do:
Query table buddies for all user friends (when ID = userid OR ID = buddyid). Having no problems with that.
Problem comes when I try to join users table to get username, username is NULL, can't find out why.
Would you like to help me?
Here's working query (but returning empty username)
SELECT username
FROM (
`users_buddies`
)
LEFT JOIN `users` ON ( 'users.id' = 'buddyid'
OR 'users.id' = 'userid' )
WHERE `userid` =1
OR `buddyid` =1
Thanks in advance for any help. I'm more than sure it's tiny bug (caused by me) but really cannot find it. Spent over one hour on this, then decided to ask.
Regards,
Tom
think it's the quotes, try this:
SELECT username
FROM users_buddies ub
LEFT JOIN users u
ON u.id In (ub.userId, ub.buddyid)
Secondly, your Where condition doesn't make sense. If you only want one name to come up then you can restrict it to userid = 1 or buddyId = 1.. (that's the same user, whether he's a user in user_buddies, or a buddy in user_buddies)
If what you want is to find all the buddies of user with userid = 1 , then try this:
SELECT b.username
FROM users_buddies ub
LEFT JOIN users b
ON b.id = ub.buddyid
Where ub.userid = 1
or even better,
Select u.username User, b.username Buddy
From users_buddies ub
LEFT JOIN users u
ON u.id = ub.userid
LEFT JOIN users b
ON u.id = ub.buddyid
Where ub.userid = 1
Tiny bug is that you are using incorrect quotes in ON condition
change
'users.id' = 'buddyid' OR 'users.id' = 'userid'
to
`users`.`id` = `buddyid` OR `users`.`id` = `userid`
Why do you use ` character for object names?
SELECT username
FROM users_buddies
LEFT JOIN users ON ( users.id = 'buddyid'
OR users.id = 'userid' )
WHERE userid =1
OR buddyid =1
Now everyone has spotted it, oughtn't it be this?
SELECT username
FROM users_buddies LEFT JOIN
users ON (users.id = buddyid OR users.id = userid)
WHERE userid = 1 OR
buddyid = 1;
What is the idea of all these ` marks, anyway?
As other people have observed, you're using the wrong quotes.
The ' character is for quoting strings, not objects. So, you're doing a pair of string comparisons. The string 'user.id' will never equal the string 'buddyid', and ditto for your other comparison, so the query returns nothing.
For quoting objects (tables, columns, etc) you must use the backquote character `.
You are only required to quotes objects if the object is named the same as a reserved word or has non-standard characters (spaces and such) in it. So, in this query, none of the quote characters are actually required.
IMO, if you must quote an object, that's a good sign that you shouldn't use that particular name.