How to build sql query from two tables? - php

Members is a table of persons who are members of a club. Various details of each member are included in this table through various columns such as ID, name, address, email, etc.
Now, any two members of this table can have a relationship. For example, if A, B, C, and D are all members of this table, then A and B can have a relation; A can C have a relation; B and D can have relations, etc. So, while member A can have a relation with all other members (such as B, C, and D, etc.), he can have a relation with any other member in, either way, i.e., it can be A-B or B-A.
For this relationship, a new table Relations has been created. This has only 3 columns; namely, ID, FirstMemberID, SecondMemberID. Here, both FirstMemberID and SecondMemberID are basically the respective IDs of members (in a relationship) from the Members table.
Now, I want to construct an SQL query (for MySQL) to select full details (all columns) from the Members table for all those members who have a relationship with a person with ID of XYZ in such a manner that XYZ is the first part of this relationship. Here XYZ is only the ID of the person and not his name.
So, I can this first query:
SELECT SecondMemberID FROM Relations WHERE FirstMemberID = XYZ;
This query gives multi-results because XYZ has relations with many members.
The other select statement is like this:
SELECT * FROM Members WHERE ID = SecondMemberID;
[Note: Here, SecondMemberID is what is returned from the first query. But, as I said, there can be many SecondMemberID here.]
My problem is how to combine the two queries in such a way that I get proper results.
I have tried various methods, like treating the results of the first query as an array and then using IN operator in the second query by using the implode method of PHP or otherwise. I have also tried various JOIN statements but without success.
What am I missing? Can you please help?

Try
SELECT Members.*
FROM Relations LEFT JOIN Members
ON (Relations.SecondMemberID=Members.ID)
WHERE Relations.FirstMemberID = XYZ;

You need a simple JOIN command in SQL. JOIN joins two tables. INNER JOIN joins them on a specific condition, i.e. concatenates two rows (one from each table) that match the condition. Condition is usually something like: table1.field1 == table2.field2 or you can use LEFT or RIGHT JOIN which will, in turn, join two rows but the right or left one can be empty.

I think you want:
SELECT SecondMemberID
FROM Relations
WHERE Id IN (SELECT SecondMemberID
FROM Members
WHERE FirstMemberID = 'XYZ');

Related

extracting data with one query instead of multiple queries and deal with it easily

Sorry for my bad english
i have a forms table in which i have columns like competition_name and team_name
secondly i have members table
each member has columns mem_name, mem_university , mem_team
means from has team_name and members also have team_name
one team can have several(upto 5) team members, i need to fetch all forms with their respective members in single query, and it should come into one array so that i can generate a table or a list, any idea?
which join should i use in this case, any dummy query for this scenario will be helpful
May be like this
SELECT forms.*,members.*
FROM forms LEFT JOIN members ON forms.form_id=members.form_id
GROUP BY forms.form_id

Php mysql query for data from two tables

i have two tables in my database. table A is USERS and table B is relations, and the following are their columns
USERS(username, avatar, specialty) and RELATIONS(username1, username2, reldir)
RELATIONS stores the relationship between users, that is if, username1 is following username2, reldir = F, and if they are both following each other, reldir=FB and vice versa, this part has worked very well but
i need to query these tables so that i return a list of users from USERS which for example user A doesnt follow but have the same specialty as A...
i tried this, but its not working well ...
$spec = the specialty of user A
SELECT a.username, a.avatar, a.specialty FROM users a, relations b WHERE a.username!=b.username2 AND (b.reldir!='F' OR b.reldir!='FB') AND a.speciality ='$spec'
the query to me seems logically correct but i could be wrong. i need help
You need to add some keys for your tables, because you have two different tables and they doesn't linked.
For example, table USERS:
id (as primary_key), username, avatar, specialty
Table RELATIONS:
user_id, username2, reldir
user_id - it is field "id" from table USERS (instead your "username1")
Then you will be able create a query like this:
SELECT a.*
FROM users a, relations b
WHERE a.id = b.users_id
AND (b.reldir != 'F' OR b.reldir != 'FB')
AND a.speciality = '$spec'
ps: if I understood your question in the right way)

Selecting data from various tables without multiple queries

MySQL - Workbench (PHP):
Tables:
TUsers (One to many relationship with TCompanies):
TUsers_CompanyID (FOREIGN KEY)
TUsers_UserName
TUsers_UserPassword
TUsers_ID (UNIQUE)
TCompanies:
TCompanies_CompanyName
TCompanies_CompanyContactNumber
TCompanies_CompanyAddress
TCompanies_ID (UNIQUE)
Is it possible to link multiple tables in a relational database without using the JOIN, or INNER JOIN query commands, without duplicating data in tables?
Thus speaking even another way of creating a relationship that makes the one table "point" to the other's data.
So that one can query the following and successfully retrieve all the data from both tables at once:
MySQL:SELECT * FROM TUsers;
See example above..
You can do it without "appearing" to use a join (ie, the word JOIN won't be in the query), but MySQL will still perform a JOIN...
SELECT *
FROM TUsers, TCompanies
WHERE TUsers_CompanyID=TCompanies_ID;
You won't be able to escape having to use a JOIN for how you want to display your data, but what you might want to do is create what's known as a VIEW, so that you don't actually have to type out the JOIN commands whenever you want to query for the user data:
CREATE VIEW UsersView AS
SELECT *
FROM TUsers a
INNER JOIN TCompanies b ON a.TUsers_CompanyID = b.TCompanies_ID
Then once the view is defined, you can just select from UsersView like so:
SELECT * FROM UsersView
...And it will return the users information as well as the joined company information. You can think of views as a way to simplify (or "compactify") more complex queries, because underneath the hood, it's actually the same thing as:
SELECT *
FROM
(
SELECT *
FROM TUsers a
INNER JOIN TCompanies b ON a.TUsers_CompanyID = b.TCompanies_ID
) UsersView

Join SQL tables

Suppose that in table "ab" I have the names of the students that get along from class "a" and class "b", identically I have table "ac" and "bc". What SQL query should I use in order to get all the combinations possible of students who can form groups (i.e. "get along together")? And how can i extend this to n classes?
For example: John from class a gets along with Jen from class b and Steff from class c, and Jen and Steff get along. Therefore John, Jen and Steff can form a group).
For this I would create two tables, a student table (id, name, class) and a relationship table (student1, student2). You might also want to add a class table for the time, location etc of the class.
A friendship would have two relationships (2,3) and (3,2) to describe it as two way. One way might be a follower or fan of another student.
This will scale up to a lot more than 3 classes.
Then you can use multiple joins to get friends of friends and so on to an arbitrary depth.
Here is a query to get friends of friends (fof):
SELECT fof_details.*
FROM relationships r
INNER JOIN relationships fof
ON r.student2 = fof.student1
INNER JOIN student fof_details
ON fof_details.id = fof.student2
WHERE r.student1 = '12';
There are also database engines made specifically for doing graph modeling like this.
http://openquery.com/blog/graph-engine-mkii
This query should return all students who can be in one group with John.
WITH ABC AS (SELECT AB.A, AB.B, AC.C FROM (SELECT * FROM AB
INNER JOIN BC
ON AB.B=BC.B)
INNER JOIN AC
ON (AC.C=BC.C AND AB.A=AC.A))
SELECT STUDENT FROM (
SELECT AB.B STUDENT FROM ABC WHERE AB.A='John'
UNION
SELECT AC.C STUDENT FROM ABC WHERE AB.A='John')
GROUP BY STUDENT
PS.: Written fast without any syntax check, hope you'll be able to bring this to work :)
The initial query can be satisfied by the code
select ab.a, ab.b, ac.c
from
ab inner join
bc on ab.b = bc.b inner join
ac on ac.a = ab.a and bc.c = ac.c
Stepping up to n classes will get progressively more complex as n=4 would be the same query with the additional three joins
inner join ad on ab.a = ad.a
inner join bd on bd.b = ab.b and ad.d = bd.d
inner join cd on cd.c = ac.c and ad.d = cd.d
2 classes requires 1 table and no joins,
3 classes requires 3 tables and 2 joins,
4 classes requires 6 tables and 5 joins
So we can see it getting progressively more complex as we proceed
First you don't want to have a table for each class. You are capturing the same type of information in multiple tables and this is generally considered a bad practice. You want to "normalize" your data so that the same data exists in one place.
Second, name your tables appropriately so that you understand what you are actually trying to build. Maybe you are generalizing to mask what your intentions for the actual implementations are by using "ab" in the question, but if you are doing this in your actual code it will hurt you in the long run.
It appears you need a people table with names and a friends table where you track who is friends with who:
create table people ( id int, name char(128) );
create table friends ( id int, person_id int, friend_id int );
Then you just need to have the query to get the groups:
SELECT person.* FROM friends
INNER JOIN friends grp
ON friends.friend_id = grp.person_id
INNER JOIN people person
ON person.id = grp.friend_id
WHERE friends.person_id = 42;

Joining multiple (4) tables in MYSQL

I have four tables I want to join and get data from. The tables look something like...
Employees (EmployeeID, GroupID[fk], EmployeeName, PhoneNum)
Positions (PositionID, PositionName)
EmployeePositions (EployeePositionID, EmployeeID[fk], PositionID[fk])
EmployeeGroup (GroupID, GroupName)
[fk] = foreign key
I want to create a query that will return all the information about an employee(given by EmployeeID). I want a query that will return the given employees Name, position(s), and group in one row.
I think it needs to involve joins, but I am not sure how to format the queries. MYSQL's manual is technical beyond my comprehension. I would be very grateful for any help.
It seems you have trouble with SQL, in general, rather than with mySQL in particular. The documentation of mySQL provides details about the various SQL expressions, but generally assume some familiarity with SQL. To get a quick start on SQL you may consider this W3schools.com primer.
The query you need is the following.
SELECT EmployeeName, PositionName, GroupName
FROM Employees E
LEFT JOIN EmployeePositions EP ON EP.EmployeeID = E.EmployeeID
LEFT JOIN Positions P ON P.PositionID = EP.PositionId
LEFT JOIN EmployeeGroup EG ON EG.GroupId = E.GroupId
WHERE E.EmployeeId = some_value
A few things to note:
The 'LEFT' in 'LEFT JOIN' will result in producing NULL in lieu of PositionName or GroupName when the corresponding tables do not have a value for the given FK. (Should only happen if the data is broken, say if for example some employees have GroupId 123 but somehow this groupid was deleted from the EmployeeGroup table.
The query returns one line per employee (1). You could use an alternative search criteria, for example WHERE EmployeeName = 'SMITH', and get a listing of all employees with that name. Indeed without a WHERE clause, you'd get a list of all employees found in Employees table.
(1) that is assuming that each employee can only have one position. If somehow some employees have more than one position (i.e. multiple rows in EmployeePositions for a given EmployeeID), you'd get several rows per employee, the Name and Group being repeated and a distinct PostionName.
Edit:
If a given employee can have multiple positions, you can use the query suggested by Tor Valamo, which uses a GROUP BY construct, with GROUP_CONCAT() to pivot all the possible positions in one single field value in the returned row.
SELECT e.EmployeeID, e.EmployeeName, e.PhoneNum,
g.GroupName, GROUP_CONCAT(p.PositionName) AS Positions
FROM Employees e
LEFT JOIN EmployeeGroup g ON g.GroupID = e.GroupID
LEFT JOIN EmployeePositions ep ON ep.EmployeeID = e.EmployeeID
LEFT JOIN Positions p ON p.PositionID = ep.PositionID
WHERE e.EmployeeID = 1
GROUP BY e.EmployeeID
Returns positions in a comma separated string on one row.

Categories