How to query for One - Many Relation - php

I have two database tables with "one to many" relationship
let say, table A and Table B
One field from Table A is a foreign key in table B
I wanna fetch just one record from table A as well as table B (given table A's primary key)
table A
id name
--------------------
1 ABC
2 XYZ
Table B
id A_id email
------------------------------------------------
1 1 temp#temp1.com
2 1 temp#temp2.com
3 1 temp#temp3.com
4 2 temp#temp4.com
4 2 temp#temp5.com
Answer should be like this (Single Record From Table B)
For a.id = 1
A.id, A.name,B.email
-------------------------
1, ABC, temp#temp1.com
For a.id = 2
A.id, A.name,B.email
-------------------------
1, XYZ, temp#temp4.com
I used this query, but it returns all the records from table B(as table B has multiple records for each record in Table A)
SELECT a.id,a.name, b.email FROM A a, B b WHERE a.id = 1 AND b.A_id = a.id

I have created a SQL Fiddle for the demo here: http://www.sqlfiddle.com/#!2/15ae7/5
The query that you can use for getting the desired output is:
SELECT
tableA.id,
tableA.name,
tableB.email
FROM tableA
LEFT OUTER JOIN tableB ON tableB.A_id = tableA.id
GROUP BY tableB.A_id;
For more information on JOINS and GROUP BY you can refer to the following pages:
http://dev.mysql.com/doc/refman/5.0/en/join.html
https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html

Try a JOIN
SELECT
a.id,
a.name,
b.email
FROM A a
LEFT JOIN B b ON b.A_id = a.id
WHERE a.id = 1;
GROUP BY b.A_id
More info on JOINS

You can use LIMIT if you want only one record.
SELECT a.id,a.name, b.email FROM A a, B b WHERE a.id = 1 AND b.A_id = a.id LIMIT 0,1
Hope this helps you.

Related

Select where joined table has the more listed values

I have 3 tables :
A: id, name
B: id, name
C: id_A, id_B
The relation is A has many B.
There is another table with the relation has many B.
What I would like to do is find the A that has the most B.id I listed.
Something like
SELECT * FROM A JOIN C ON A.id=C.id_A JOIN B ON B.id=C.id_B WHERE B.ID HAVE_MOST(5,22,39,110,235);
It will return the first A that have all the values and if it's not found, it will return the first A that have a combination of 4 of those values, etc.
Is this possible in mysql ?
This seems to do the job :
SELECT *, count(A.id) as number FROM A JOIN C ON A.id=C.id_A JOIN B ON B.id=C.id_B WHERE B.ID IN (5,22,39,110,235) GROUP BY A.id ORDER BY number DESC LIMIT 1

duplicate record querying multiple table rows

I have this sql to query from different tables
SELECT *
FROM `person`
LEFT JOIN person_address
ON person_address.person_id=person.person_id
LEFT JOIN address_type
ON address_type.address_type_id=person_address.address_type_id
it return this data,
It's really tedious to achieve this json format
//json
[{
"person_id":"1",
"full_name":"john",
"scores": [{
"address_type":"billing",
"address_name":"Spain"
},{
"address_type":"home",
"address_name":"USA"
}]
}]
I should fix my sql query or it's that tedious I have to do manual looping using PHP to produce the json?
Tried DISTINCT
https://i.imgur.com/tZFvKAD.png
doesn't seems to work
here is a supper simplified version of what I am talking about.
Given this schema ( simple Many To Many )
CREATE TABLE a(
id INT(10)
);
INSERT INTO a (id)VALUES(1);
INSERT INTO a (id)VALUES(2);
CREATE TABLE b(
a_id INT(10),
c_id INT(10)
);
INSERT INTO b (a_id,c_id)VALUES(1,1);
INSERT INTO b (a_id,c_id)VALUES(1,2);
INSERT INTO b (a_id,c_id)VALUES(2,1);
INSERT INTO b (a_id,c_id)VALUES(2,2);
CREATE TABLE c(
id INT(10),
val VARCHAR(255)
);
INSERT INTO c (id,val)VALUES(1,'one');
Now if you run this query:
SELECT
c.val AS c_val
FROM
a
JOIN b ON a.id = b.a_id
JOIN c ON b.c_id = c.id
WHERE
c.id = 1;
You will get this result
'one'
'one'
But if you run this query
SELECT
b.a_id,
b.c_id,
c.val AS c_val
FROM
a
JOIN b ON a.id = b.a_id
JOIN c ON b.c_id = c.id;
Which is just display all you will see this
a_id | c_id | c_val
1 | 1 | one
2 | 1 | one
AS seen in this DB fiddle
https://www.db-fiddle.com/f/fZnRCSXeu3wYVFzn4NBjC5/0
This is pretty clear why in this simple example, but in a more complicated case it may not be as clear. This is especially true if the where clause matches multiple rows in the last table.
Besides that you should have the key in the bridge table ( b in the above example ) set as a compound primary key on the id's from the other 2 tables.
Now the way to fix the first query is to simply add DISTINCT to it
SELECT DISTINCT
c.val AS c_val
FROM
a
JOIN b ON a.id = b.a_id
JOIN c ON b.c_id = c.id
WHERE
c.id = 1;
Now the output is
'one'
AS seen in the last query in this updated fiddle
https://www.db-fiddle.com/f/fZnRCSXeu3wYVFzn4NBjC5/1

Multiple values from Joining three tables

I have to get A.Ref_id, B.Ref_id and B_Id's Ref_id
Table A_B having Column_A_ID and Column_B_ID
Table A having ID, Ref_id, Name, B_Id (This is the B.ID from table B)
Table B having ID, Ref_id, Name
Currently I'm having the following query
SELECT A.Ref_id as A_Ref_Id, B.Ref_id as B_Ref_Id, B_Id
FROM A_B
JOIN A on A_B.Column_A_ID = A.Id
JOIN B on A_B.Column_B_ID = B.Id
JOIN B AS Main_B on B.id = A.B_id;
By this query I'm getting the A.Ref_Id and B.Ref_Id columns correctly as they are showing their relevant Ref_id but for B_Id I want to have the Ref_id and it is showing the B.id instead.
You want this (right?): The value of B.Ref_id in the row where B.ID = A.B_Id while this row in turn must have A.ID=A_B.Column_A_ID. And the whole thing for every row in A_B:
SELECT A.Ref_id as A_Ref_id, B.Ref_id as B_Ref_id, Main_B.Ref_id
FROM A_B
JOIN A ON A_B.Column_A_ID = A.Id
JOIN B ON A_B.Column_B_ID = B.Id
JOIN B AS Main_B on Main_B.id = A.B_id;
(Last line of code with the important correction which was proposed by #Mojtaba)
So far, I see the ON condition of the last join has to use the alias name of table B:
SELECT A.Ref_id as A_Ref_Id, B.Ref_id as B_Ref_Id, B_Id
FROM A_B
JOIN A on A_B.Column_A_ID = A.Id
JOIN B on A_B.Column_B_ID = B.Id
JOIN B AS Main_B on Main_B.id = A.B_id;
By the way, having some example in sqlFiddle could be more helpful

Multiple WHERE conditions in 2 tables in MySQL

I have 2 tables as follows:
table1
ID Name Test
A011 John 1
A012 Lynda 1
A013 Micheal 1
A014 Jack 0
A021 Joe 1
A015 Paul 0
table2
ID Done
A011 1
A012 1
I want to select all rows from table1 that have an ID where the 3 first letters are equal to A01, and the test field is 1, and also the ID is not present in table2.
I tried this query:
SELECT a.* FROM table1 a LEFT JOIN table2 b ON a.ID = b.ID
WHERE a.test = 1 AND b.ID IS NULL
The result from that is 2 rows with ID A013 and A021. I tried to use LEFT(ID,3) to get the ID with A01, however, I couldn't achieve what I want.
How can I filter only the records where the ID starts with A01?
Try this, it will give you the desired result
SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 ON t1.userid = t2.userid WHERE LEFT(t1.userid , 3) LIKE '%A01%' AND t1.userid NOT IN (SELECT userid from table2)
SELECT * FROM table1
WHERE test = 1
AND ID LIKE "AO1%"
AND ID NOT IN (SELECT ID from table2)

php mysql select dynamically within 2 tables

table A id name Bid Cid Wheretolook 1 aaa
1 0
B 2 bbb
2 0
B 3 bbb
0 1
C
Table B id transactiondetails 1
zzz 2 xxx
Table C id transactiondetails 1
yyy
I have 3 tables right here table A holds foreign key for the two tables Table B and Table C. These two tables don't have the same information inside that's what I'm suppose to get. Is there a way to select all of the information from table B and C using mysql SELECT statement to gather all the transactiondetails
SELECT
a.id,
a.name,
COALESCE(b.transactiondetails, c.transactiondetails) AS transactiondetails
FROM TableA a
LEFT JOIN TableB b ON a.Bid = b.id
LEFT JOIN TableC c ON a.Cid = c.id
The Wheretolook column seems to be unnecessary if there must be one 0 in Bid and Cid.

Categories