SQL SELECT * FROM 2 tables - sql

I am building a small database app for friends where table 1 is contacts and table 2 is users. I can find email on both (One as the loggued in user and the other as the owner of the contact)
SELECT *
FROM contacts
WHERE contacts.username = users.email
I try to show all contacts fields where username is equal to already loggued in users (email)
Thanks you very much!

It sounds like you're trying to JOIN two tables together. Ideally, you don't want to use the email as the primary key on a table (the smaller the data, the faster your JOIN will be); a better option would be to add an auto-incrementing Id (integer) to both the Contacts and Users tables, set as the primary key (unique identifier). Joining on integers is much faster, as integers are 4 bytes per row, vs string which (in MySQL) is 1 per character length (latin1 encoding) + 1 byte.
Anyway, back to the original question. I believe the query you're looking for (MySQL syntax) is:
SELECT c.Id, c.Col1, u.Col2, ...
FROM contacts AS c
INNER JOIN users AS u ON u.email = c.username
Additionally, I would avoid the use of *, as it slows down the query a bit. Instead, try to specify the exact columns you need.

Try the following. Also, I would suggest you learn about joins in SQL.
SELECT *
FROM contacts
INNER JOIN
users on contacts.username = users.email

Use Inner Join:
SELECT *
FROM contacts as c
INNER JOIN
users as u on u.email = c.username

Related

How to select records from database table which has to user id (created_by_user, given_to_user) and replace users id by usernames?

This is task table:
This is user table:
I want to select user tasks.
I would give from backend ("given_to_user) id.
But The thing is I want that SELECTED data would have usernames instead of Id which is (created_by_user and given_to_user).
SELECTED table would look like this.
Example:
How to achieve what I want?
Or maybe I designed poorly my tables that It is difficult to select data I need? :)
task table has to id values that are foreign keys to user table.
I tried many thinks but couldn't get desired result.
You did not design poorly the tables.
In fact this is common practice to store the ids that reference columns in other tables. You just need to learn to implement joins:
SELECT
task.id, task.title, task.information, user.usename AS created_by, user2.usename AS given_to
FROM
(task INNER JOIN user ON task.created_by_user = user.id)
INNER JOIN user AS user2 ON task.created_by_user = user2.id;
Do you just want two joins?
select t.*, uc.username as created_by_username,
ug.username as given_to_username
from task t left join
users uc
on t.created_by_user = uc.id left join
users ug
on t.given_to_user = ug.id;
This uses left join in case one of the user ids is missing.

Query two joins on the same value and table

I'm having trouble doing the following query. The idea is that I have two tables Stores and Users. In Stores I have the columns store_owners and store_last_modified, both values are integer that are related to the id of dbo.Users. How I can display the name that is stored in users related to the two columns. Like that:
select stores.name , users.name as name_store_owner , users.name as name_store_last_modified
from stores
LEFT JOIN users ON stores.store_owners=users.id (related to name_store_owner)
LEFT JOIN users ON stores.store_last_modified=users.id (related to name_store_last_modified)
How do I do that?
Thank you in advance.
You need to give the tables aliases, so you can refer to the same table twice in the from clause. In addition, you need to refer to the right table (users not stores):
select s.name, uo.name as name_store_owner, um.name as name_store_last_modified
from stores s left join
users uo
on s.store_owners = uo.id left join
users um
on s.store_last_modified = um.id
It appears that the condition can be checked without referring the table twice.
select * from
stores s
left join
users u on u.id = s.store_owners
and u.id = s.store_last_modified
From your question it appears that user id (id) should match with both the columns in the stores table for a single row.

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'

Using Join to parse out duplicate data

I am having a bit of a problem here with this statement below using tables:
[Users] Name,Email,Subscribed
[Email] Name,Email,Subscribed
Basically what needs to be accomplished is all the Subscribed Users in the Users table need to be checked against the users in the Email table to see if they exist in the table or not, and only return the users in the Users table which are not found in the Email table.
Here is the statement I've used, but it returns millions of rows and takes forever, and it is returning every email address in the Email table, I don't think this is the best way to approach this issue because it is not returning accurate data. Any thoughts?
SELECT Distinct c.Name,c.Email from Users c
INNER JOIN Email e on c.Email <> e.Email
WHERE c.Subscribed=1
I think this is what you are looking for.
SELECT c.Name,c.Email
FROM Users c LEFT JOIN Email e ON (c.email=e.email)
WHERE (e.email is null) and (c.subscribed=1)
The INNER JOIN in your query with no ON clause is why you are getting wacky results.
change the <> to =
You are doing an join on non-equality so that is why your result size is exploding.
On a side note - check into foreign keys going forward - they make this type of cross table referential integrity a non-issue.
UPDATE - if you want results in one table that are not in the other do:
select * from table1 where email not in (select distinct email from table2);
This will give you all the records in table1 that don't match an email in table 2.
HTH
You will want to use a LEFT JOIN to accomplish this:
SELECT Distinct u.Name, u.Email
FROM Users AS u
LEFT JOIN Email AS e ON u.Email = e.Email
WHERE e.Email IS NULL
AND u.Subscribed = 1
Graphical explanation of JOINS may be helpful
I strongly recommend using Foreign Keys to maintain referential integrity.

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