Join Three tables in mysql with weird requirement - php

I have three tables in my db.
Table A has the fields
KEYID | KeyName
27 | Income
28 | Account Number
Table B has the fields
UserID | Email | Name | Phone
481 | test#gmail.com | test | 99999999
Table C has the fields
ID | KEYID | UserID | Value
1 | 27 | 481 | 10,000
I need to display the table fields headers are:
UserID | Email | Name | Phone | Income
and the table values should be like this:
481 | test#gmail.com | test | 99999999 | 10,000
I can get the KeyIDs which should be displayed in the table. In this example the KeyIDs string is '27' . I tried with joining and i can fetch & display the value in the table. but i dont know how i can show the key name as table header.
Any Idea.?

You can use a pair of inner join
select b.UserID, b.Email , b.Name, c.value as income
from tableB as b inner join tableC as C on b.userID = c.userId
inner join tableA as a on a.keyID = c.keyID
and a.keyname = 'Income';
and the query you provided in comment
select
b.UserID
, b.Email
, b.Name
, Group_Concat(Distinct Concat(c.keyID,’^:^’,c.value)
Order By c.id Separator ‘;’) As Keyvalues
from tableB as b
inner join tableC as C on b.userID = c.userId
inner join tableA as a on a.keyID = c.keyID;
and with CASE should be
select
b.UserID
, b.Email
, b.Name
, Group_Concat(Distinct CASE
WHEN c.keyID IN ('1,23,10') THEN Concat(c.keyID,’^:^’,c.value) END
Order By c.id Separator ‘;’) As Keyvalues
from tableB as b
inner join tableC as C on b.userID = c.userId
inner join tableA as a on a.keyID = c.keyID;

This query should help to get your desire result.
select b.UserID, b.Email, b.Name, b.Phone, c.Value as Income
from table_b as b
JOIN table_c as c ON (b.UserID = c.UserID)
where c.KEYID = 27

Try this:
SELECT b.userid, b.email, b.name, b.phone, c.value as income
FROM a
LEFT JOIN c on c.keyid = a.keyid
LEFT JOIN b ob b.userid = c.userid

Related

Join statement for intersection table

I'd like to connect a user to one or multiple cars. The tables look like this:
table_a
id name
1 tom
2 max
table_b
id car
1 car1
2 car2
3 car3
table_ab
id id_a id_b
1 1 1
2 1 2
3 2 1
Which is the correct select statement so that the result is like:
tom has car1 and 2
max has car1
I don't get it to work with INNER JOIN.. what is the correct statement?
SELECT `name`,`car` FROM table_a a
INNER JOIN table_ab ab ON a.id = ab.id_a
INNER JOIN table_b b ON ab.id_b = b.id
PS: You can also do this without any joins, in some cases, its faster and cleaner.
SELECT `name`,`car` FROM table_a a,table_b b, table_ab ab
WHERE a.id = ab.id_a AND ab.id_b = b.id
In this case, DESCRIBE showed identical results, so either options will work for you.
I think you want joins and aggregation:
select a.name, group_concat(car) as cars
from ab join
a
on a.id = ab.id_a join
b
on b.id = ab.id_b
group by a.id, a.name;
You need two join
select a.name, b.car
from table_ab ab
inner join table_a a ON a.id = ab.id_a
inner join table_b b ON b.id = ab.id_b
You must join the tables, group by name and use group_concat() combined with concat():
select concat(a.name, ' has ', group_concat(car separator ' and ')) col
from table_a a
inner join table_ab ab on ab.id_a = a.id
inner join table_b b on ab.id_b = b.id
group by a.id, a.name
See the demo.
Results:
| col |
| --------------------- |
| tom has car1 and car2 |
| max has car1 |

INNER JOIN mysql from one table to another where its based on multiples of same id

I have an table called product which lets say looks like this:
product
product_id | cults_id1 | cults_id2 | cults_id3
-----------------------------------------------------
1 | 5 | 4 | 2
And the also a table thats based on this called cultivar:
cultivar
cults_id | cults_name |
-------------------------
1 | berries |
2 | fruit |
3 | choc |
4 | wood |
5 | mysql! |
How would i create an JOIN query to get each name from cultivar table where the product id in product table is the same as cults_id in the cultivar table?
OUTPUT
My Product Cults :
berries, Mysql!, wood, fruit
Dont think an INNER JOIN is the way to go but i would have tried something like this:
$query = "SELECT cultivars.cults_name
FROM product
INNER JOIN wine_cultivar ON wine_cultivar.cults_id = product.cultivar_1_id
INNER JOIN wine_cultivar ON wine_cultivar.cults_id = product.cultivar_2_id
INNER JOIN wine_cultivar ON wine_cultivar.cults_id = product.cultivar_3_id
INNER JOIN wine_cultivar ON wine_cultivar.cults_id = product.cultivar_4_id
";
i tried a inner join multiple times targeting all the ids but dont think this is the way to go. Also this is just a part of my sql query.
Simply assign table aliases to each self join and then reference corresponding fields in SELECT.
Right now you join to same table but do not provide aliases to distinguish between the four which MySQL should have raised its Error #1066 for this attempt.
SELECT p.product_image_path, p.product_id, p.brand_name, p.product_name, b.botttle_size, v.vintage,
t.wine_type_blend, p.price, p.quantity, p.time_created, p.reference_number, p.shipping_cost,
c1.cultivar_type as cultivar_type1, c2.cultivar_type as cultivar_type2,
c3.cultivar_type as cultivar_type3, c4.cultivar_type as cultivar_type4
FROM product p
INNER JOIN wine_bottle b ON b.bottle_id = p.bottle_id
INNER JOIN wine_vintage v ON v.vintage_id = p.vintage_id
INNER JOIN wine_type t ON t.type_id = p.type_id
INNER JOIN wine_cultivar c1 ON c1.cultivar_id = p.cultivar_1_id
INNER JOIN wine_cultivar c2 ON c2.cultivar_id = p.cultivar_2_id
INNER JOIN wine_cultivar c3 ON c3.cultivar_id = p.cultivar_3_id
INNER JOIN wine_cultivar c4 ON c4.cultivar_id = p.cultivar_4_id

MYSQL joining three tables

I have a simple multiple school management system and I am trying to get total number of teachers, and total number of students for a specific school. My table structures are as follows:
teachers
--------------------------
id | schoolid | Name | etc...
--------------------------
1 | 1 | Bob |
2 | 1 | Sarah|
3 | 2 | John |
students
--------------------------
id | schoolid | Name | etc...
--------------------------
1 | 1 | Jack |
2 | 1 | David|
3 | 2 | Adam |
schools
--------------------------
id | Name | etc...
---------------------------
1 | River Park High |
2 | Stirling High |
I can count just all teachers with the following query:
SELECT COUNT(a.id) AS `totalteachers`
FROM teachers a
LEFT JOIN schools b ON a.schoolid = b.id WHERE b.id = '1'
and similarly I can count the number of teachers with the following query:
SELECT COUNT(a.id) AS `totalstudents`
FROM students a
LEFT JOIN schools b ON a.schoolid = b.id WHERE b.id = '1'
I am however struggling with trying to combine these two queries to get a simple result like this:
totalstudents | totalteachers
--------------------------------
2 | 2
I have tried the following:
SELECT COUNT(a.id) as `totalteachers`, COUNT(c.id) as `totalstudents`
FROM teachers a
LEFT JOIN schools b ON a.schoolid = b.id
LEFT JOIN students c ON c.schoolid=b.id WHERE b.id = '5'
You can do something like this
SELECT
id, name, s.total AS totalstudents, t.total AS totalteachers
FROM schools
JOIN (SELECT schoolid, COUNT(id) AS total FROM teachers GROUP BY schoolid)
AS t ON t.schoolid = id
JOIN (SELECT schoolid, COUNT(id) AS total FROM students GROUP BY schoolid)
AS s ON s.schoolid = id
then you can add where id = 2 or whatever to limit the school.
The problem with the multiple left joins is it generates additional records for each teacher to each student; artifically inflating your counts
There's four ways to solve this: (best imo is what Andrew bone did)
Simply select inline without the joins so the counts are not inflated. (most desirable in my mind as it's easy to maintain)
SELECT (SELECT COUNT(a.id) AS `totalteachers`
FROM teachers a
WHERE A.SchoolID = '1') as TotalTeachers
, (SELECT COUNT(a.id) AS `totalstudents`
FROM students a
WHERE a.SchoolID = '1') as TotalStudents
Use subqueries to get the counts first before the joins, then join. Since count will always be 1 a cross join works.
SELECT totalTeachers, totalStudents
FROM (SELECT COUNT(a.id) AS `totalteachers`
FROM teachers a
LEFT JOIN schools b
ON a.schoolid = b.id
WHERE b.id = '1')
CROSS JOIN (SELECT COUNT(a.id) AS `totalstudents`
FROM students a
LEFT JOIN schools b ON a.schoolid = b.id
WHERE b.id = '1')
Use key word distinct within the count so as not to replicate the counts and negate the artificial inflation (least desirable in my mind as this hides the artifical count increase)
SELECT COUNT(distinct a.id) as `totalteachers`, COUNT(distinct c.id) as `totalstudents`
FROM teachers a
LEFT JOIN schools b ON a.schoolid = b.id
LEFT JOIN students c ON c.schoolid=b.id WHERE b.id = '5'
Another way would be to use a window functions, however these are not available in mySQL.
SELECT COUNT(t.id) AS TotalTeachers, COUNT(st.id) AS TotalStudents
FROM schools s
INNER JOIN teachers t
ON s.id = t.schoolid
INNER JOIN students st
ON s.id = st.schoolid
Try this SQL. I havn't try it but it should work.

mysql count number of votes in votes table

I have 3 tables named election_cand, candidate and votes:
election_cand table:
ele_can_id | election_id | candidate_id
candidate table:
id | canname | canadd | canphone | canmail | candes | canphoto
votes table:
voteid | candidateid | voterid | electionid
my tables with data are:
I want the desired result as
I write the mysql query as:
SELECT a.*,b.*,c.*, count(voteid) AS numrows
FROM election_cand a
left join votes b on a.election_id=b.electionid
left join candidate c on a.candidate_id=c.id
where a.election_id='$get_ele_id' group by a.candidate_id
As I see you only need this query:
SELECT
c.*, COUNT(e.ele_can_id) AS numrows
FROM candidate c
Left Join election_cand e on c.id = e.candidate_id
GROUP BY c.id
describe your schema so we can help you more.
Try this code:
SELECT
c.*, COUNT(v.candidateid) FROM candidate c
LEFT JOIN votes v ON c.id = v.candidateid
WHERE c.id IN
( SELECT candidate_id FROM election_cand WHERE election_id = 4 )
GROUP BY v.candidateid

MYSQL QUERY to join multiple tables

I am looking for single query where I can connect multiple tables.
The Query is as follows
`
SELECT
a.name as module_name,
a.id,
b.id as subject_id,
b.SUBJECT_name,
c.id as course_id,
c.course_name,
d.id as cordinator_id,
d.cordinator_name
FROM module_table a
LEFT JOIN subject_table b ON b.id = a.subject_id
LEFT JOIN course_table c ON c.id = a.course_id
LEFT JOIN cordinator_table d ON d.id = a.cordinator_ids
WHERE a.id = $somevalue
ORDER BY a.id DESC
`
Above query is producing error and when I am connecting the two tables Its showing all right
SELECT
a.name as module_name,
a.id,
b.id as subject_id,
b.SUBJECT_name
FROM module_table a
LEFT JOIN subject_table b ON b.id = a.subject_id
WHERE a.id = $somevalue
ORDER BY a.id DESC`
The first Table has all foreign keys for subject and course table, further subject table is connected to coordinator table with common id column.. I want the corresponding names of the id given in the module table..
The last table is the result of query I want from where I can collect my required data
My table structures are below
MODULE CAN BE INCLUDED ONLY IN A SUBJECT AND SUBJECT CAN BE INCLUDED IN COURSE
EACH SUBJECT CAN HAVE ANY NUMBER OF CORDINATORS WHICH I AM KEEPING THEM AS JSON value
-----------------------------------------------------------------------
MODULE TABLE
_____________________________________________________
id | subject_id | course_id | cordinator_id | name
-----------------------------------------------------------------------
COURSE TABLE
__________________
id | course_name
-----------------------------------------------------------------------
SUBJECT TABLE
_________________________________________________
id | course_id | cordinator_id | SUBJECT_name
-----------------------------------------------------------------------
CORDINATOR TABLE
______________________________________
id | cordinator_ids | cordinator_name
Result TABLE
___________________________________________________________________________________________
id | module_name | subject_id | subject_name | course_id | course_name | cordinator_ids
I am able to join two tables successfully with LEFT Join but on third it is reporting an error.
The problem is that you have a few typos and forgot to JOIN course_table.
Here is the right query:
SELECT
a.name as module_name,
a.id,
b.id as subject_id,
b.SUBJECT_name,
c.id as course_id,
c.course_name,
d.id as cordinator_id,
d.cordinator_name
FROM module_table a
LEFT JOIN subject_table b ON b.id = a.subject_id
LEFT JOIN course_table c ON c.id = a.course_id
LEFT JOIN cordinator_table d ON d.id = a.cordinator_id
WHERE a.id = $somevalue
ORDER BY a.id DESC
On this line:
b.SUBJECT_name,
you had to put uppercase "SUBJECT_name" as in your table subject_table schema.
And your query was lacking this JOIN to allow you to select course_table fields:
LEFT JOIN course_table c ON c.id = a.course_id

Categories