I am having three tables
user(id,fname,lname)
picture(picid,pic_path,userid)
friends(friend_of,friends_id,status)
I want to fetch id,fname,lname,pic_path for all friends_id of friends_of=1
picture path may be null
Thankx in advance.
What you're looking for is called a join. In particular, you're looking for a JOIN and a LEFT JOIN.
SELECT
user.id, user.fname, user.lname, picture.pic_path
FROM
friends
JOIN user
ON user.id = friends_id
LEFT JOIN picture
ON userid = user.id
WHERE
friends.friend_of = 1
This will only work though if there's a maximum of 1 entry in picture.
Though this answers your immediate question, I suggest you become very familiar with joins. They're one of the fundamental operations of a relational database. (Note that a join essentially is a mathematical relation)
Try this
SELECT u.*,p.*,f.*
FROM USER u
LEFT JOIN picture p ON p.user_id = id
INNER JOIN friends f ON f.friends_of = u.id
WHERE f.friends_id = 1
For querys like that you need to understand and employ the relations between your entities. Then you work in two steps: selection and projection and contrary to what SQL-syntax may imply the part before the FROM keyword is the projection.
First we compile data. Clearly we need the data from all three tables and we need it once. So at first we construct all possible combinations, by joining all three tables. In SQL this is done in the FROM part, i.e.
FROM friends f, picture p, user u
f, p and u are aliases which serve the purpose of saving us the efford of typing the full table names in the following.
Now we have all possible combinations. Let's select the ones we want:
I suppose every picture in your DB belongs to a user which is stored in your DB as well. So my assumption is that you only want pictures associated to a user. Hence we have a first restrictions on all the combinations we made before! The restriction derived from the (probable) meaning of the data stored in you database and stated as:
u.id = p.userid
(Notice: by applying this restriction to combination above we "select" only certain combinations.)
Then you already stated another restrictions as a request "friends_of=1" to associate this constraint on the combination we write:
f.friends_of=1
Then we combine your request "friends_of=1" with the other data by:
f.friend_of = u.id
This constraint selects only those users who are a friend of somebody. Now we can combine these constraints. As we want all constraints to be satisfied we AND them in a WHERE statement:
WHERE u.id = p.userid AND f.friend_of = u.id AND f.friends_of=1
The ordering does not affect meaning (in this case. But let's rethink those constraints:
u.id = p.userid : we want information about the user and the pictures associated with that user
f.friend_of = u.id : we are looking for a users who are friends of somebody
f.friends_of=1 : we are looking for friends of a particular somebody
Now we project the data stored in our DB to what we want. We want all the user data and picture paths. In SQL:
SELECT u.*,p.pic_path
Now we put everything together.
SELECT u.*,p.pic_path FROM friends f, picture p, user u WHERE u.id = p.userid AND f.friend_of = u.id AND f.friends_of=1
To allow for friends that don't have a picture associated with them (note: that's very different to pic_path being NULL) you need an outer join, which means you also want combinations with empty sets. That's where my MySQL is not so good but I'd guess you'd generate all combinations you want (and many more) with:
FROM friends f JOIN user u LEFT JOIN picture p ON u.id = p.userid
and
SELECT u.*,p.pic_path FROM friends f JOIN user u LEFT JOIN picture p WHERE f.friend_of = u.id AND f.friends_of=1
Notice, that the constraint that may be violated has been made explicit by moving it from the general selection to the generation of the data combinations as a rule on how to create combinations. And yes, it's a shortcut instead of following through the idea of selection and projection.
Related
i'm a beginner on MYSQL db and i'm trying to play around with the query and relations.
i have created 2 tables, one is 'users' which contain the field staff_ID and the other is 'reports' which also contain the table field staff_ID of the user submitting the reports.
on the relations (see picture) i have connect the 2 staff id field.
every user can submit more than one reports, so i'm try to query and get only the reports of one users(staff_ID).
I understood i have to use the JOIN keyword in order to obtain the data..
i tried the following query but it gave me all the result for all the users.
SELECT u.staff_ID
, u.Name
, r.id_report_show
, r.date_report
FROM users u
JOIN reports r
ON r.staff_ID = u.staff_ID
but I would like to have the report only of one specific user like staff_ID = 04033
probably i understood wrong how this query JOIN work, i'm looking for some help.
Thanks
You are almost there. Your join is perfect. You just need a where clause.
SELECT users.staff_ID, users.Name, reports.id_report_show, reports.date_report
FROM `users` INNER JOIN reports ON reports.staff_ID = users.staff_ID
where users.staff_ID = 04033
Or you can also mention it within on clauses:
SELECT users.staff_ID, users.Name, reports.id_report_show, reports.date_report
FROM `users` INNER JOIN reports
ON reports.staff_ID = users.staff_ID and users.staff_ID = 04033
Since it's inner join both the query will produce same output. But for left join those might produce different result. It's a good practice to use where clause instead of mentioning the condition in on clause.
How can we show the 'inverse' of the Inner Join. For example, I have a list of actual transactions of customers that went thru the payment processor, in this case 'Paypal' but they never clicked the 'Back to Merchant' tab so that we can process their userid and password.
This script shows ALL the people that are in the customer list and their associated place in the users database:
SELECT
`Transactions List`.`Customer Email`,
users.Email,
`Transactions List`.`Transaction ID`,
users.`Name`,
users.Phone
FROM
`Transactions List`
INNER JOIN users ON `Transactions List`.`Customer Email` = users.Email
What I'm seeking to do is show the INVERSE of that. i.e. all the people who LOST their way. They DO appear in the TRANSACTIONS LIST table but do NOT appear in the USERS table.
Anyone have an idea how to convert this MYSQL Query into the Inverse so we can quickly identify which customers did not get user accounts?
There's an existing post "Inner join inverse Php MySQL" here that wasn't answered that asks a similar question. Perhaps the person asking the question was not clear enough: Inner join inverse Php mysql
also
What is the difference between “INNER JOIN” and “OUTER JOIN”?
What is the difference between "INNER JOIN" and "OUTER JOIN"?
but neither of these methods actually do what I want the script to do.
What I'm seeking to do is show [...] all the people who [...] appear in the TRANSACTIONS LIST table but do NOT appear in the USERS table.
You could use not exists:
select t.*
from transactions_list t
where not exists (
select 1 from users u where t.customer_email = u.email
)
Another way to phrase this is to use an anti-left join (this is more in the spirit of your question, that relates to joins):
select t.*
from transactions_list t
left join users u on t.customer_email = u.email
where u.email is null
This means: try to join each transaction with a user, and filter on those that did not match.
select t.*
from `Transactions List` t
left join users u on t.`Customer Email` = u.email
where u.email is null
Given the above syntax and the name of the table in the database as specified above this is the correct answer. Thank you to GMB for answering the question. For other readers, keep in mind that if your database tables include spaces in their names or field names then you must use the scare quotes to identify your table or field names. This is commonly used when importing tables into MySQL from 3rd party tools.
I have two database tables, one is named "articles", and the other one is "users"
the structure of articles is as follows:
article_id article_title user_id
The structure of users is:
user_id user_fullname password
I wish to retrieve a list of all articles from the table "articles", but would like to attach each article's user_fullname. I think this may require "LEFT JOIN", so I made the following attempt in MySQL prompt.
> SELECT * FROM articles A LEFT JOIN users U on U.user_id = A.user_id;
but somehow I don't see the user_fullname printed out with this command. I need some help with the correct syntax. Thank you!
A full join seems more appropriate, each article must have an author, so there should be a corresponding entry in the users table:
SELECT *
FROM articles a
JOIN users u USING(user_id);
Note: USING here is the same as ON a.user_id = b.user_id and can only be used if the column name is the same in both tables.
I'm having an issue with a mysql query for a search screen at work. I've got the query working using the code I'll post below, but I'm suspicious there is a better way to do it. Mysql are pretty newbie really, I just figure it out as I go along, or try to.
Here is the concept of the database:
There is an Entity, Address, Contact, Client, Group and Facility table involved in my query.
Each Client, Group and Facility is an "Entity" for lack of a better word. Each Entity has it's own Entity ID in the Entity table.
The Entity table houses an address record id and a contact record id.
On the facility search screen, if a user searches a phone number I want to search through the client and group records as well as the facility records. And then return any matching facility information as I normally would.
Here's what I've got so far(I'm doing nothing for address outside of facility records just yet and I've hardcoded some things for the sake of explaining myself):
SELECT facility.FacilityID, facility.Name, contact.PhoneNumber, addy.State addy.ZipCode, facility.ProductionFacilityID,
facility.ProductionEntityID
FROM Facility facility
INNER JOIN ClientGroup cg ON facility.GroupID = cg.GroupID
INNER JOIN Client c ON cg.ClientID = c.ClientID
INNER JOIN Entity e ON facility.FacilityID = e.EntityID
INNER JOIN Entity eg ON cg.GroupID = eg.EntityID
INNER JOIN Entity ec ON c.ClientID = ec.EntityID
INNER JOIN Contact contact ON e.BillingContactID = contact.ContactID
INNER JOIN Contact contactg ON eg.BillingContactID = contactg.ContactID
INNER JOIN Contact cc ON ec.BillingContactID = cc.ContactID
INNER JOIN Address addy ON addy.AddressID = e.PhysicalAddressID
WHERE (facility.FacilityID like '%$searchfor%'
OR contactg.PhoneNumber like '%$searchfor%'
OR cc.PhoneNumber like '%$searchfor%')
AND facility.IsRowActive=1
ORDER BY $searchtype";
Thanks in advance for the help!
Yes, the better way to do this for maintenance purposes is to create a view of only the inner joins and querying the view. Remember in terms of performance there would be little by way of improvement but maintenance of the code would become much easier.
Given your purpose the inner joins are not entirely avoidable unless you decide to change the structure of the tables
I'm a beginner in queries and I'm struggling with one of them. Here are the two tables involved :
The askstobefriends table permit a user to add a friend in the application I m developping. The relational form of it is :
AskToBeFriends(ID (long), #UserAsker (long), #UserAsked (long), Accept (tinyInt))
So with this table we can see who asked to be friend and if it was accepted ...
The query I m trying to realize would permit to list all the user's friends from his ID and also return the friendship statut (accept field ==> waiting for an answer, accepted or refused).
Speretaly, it would be something like that :
SELECT Accept, UserAsker, UserAsked
FROM askstobefriends
WHERE UserAsker = '".$userID."' OR UserAsked = '".$userID."' ";
==> first issue : it can either be the user who asked to be friend with someone or the opposit, that why i've put and OR. After that, I d like that for everyfriend founded there's these informations :
SELECT colUserID, colUserLogin, colUserName, colUserFirstname
FROM userTable
WHERE colUserID == FRIEND
So I guess I need to do a join query, and in my join I have to be sure that I'm using the right foreign key from the asktobefriends tablefor each cases !! (once the key could be UserAsked and another time UserAsker depending on who asked to be friends :S )
Does anyone have a clue please :S ?? Thanks ;-) !!
Your design is wrong. A User asks to be friend of another User, so "Ask_to_be_friend" is the relation, and the cardinality is many to many, so the design will looks like this:
User_User_ID is UserAsker.
User_USer_ID1 is UserAskedtobefriend
and the query could be like (you'll get all the users that user_user_ID Asks to be friend of):
Select U.* from User as U
Join Ask_to_be_friend as A on
U.user_ID = A.User_user_ID
--where a.accept=1 if you add this, this will give
--you all the friends ID of the user_ID table User
If you want to get the names or extra info of the askedtobefriend you'll need a extra Join
Select U.* from User as U
Join Ask_to_be_friend as A on
U.user_ID = A.User_user_ID
Join User as U2 on
A.User_User_ID1=u2.User_ID
--where a.accept=1 ,with this you'll with get only the friends
You could join the tables using criteria that ensure only friends of :userID are returned. For example:
SELECT u.*, a.Accept
FROM askstobefriends a JOIN userTable u ON (:userID, u.colUserID) IN (
(a.UserAsker, a.UserAsked),
(a.UserAsked, a.UserAsker)
)