My question pertains to joining data based on a specific condition.
For example, in table A there is a column known as user_type. If user_type is 1, I want to do an INNER JOIN from table B. However, if user_type is 2 in Table A, I want to do an INNER JOIN from table C.
Much appreciated if someone could iron out the syntax in PHP :-)
Use INNER JOIN with both tables as usual, and use a CASE statement just to show table B or table C result.
SELECT CASE WHEN tableA.user_type = 1 THEN tableB.user_type
WHEN tableA.user_type = 2 THEN tableC.user_type
END as user_type
FROM tableA
INNER JOIN tableB
ON tableA.id = tableB.id
INNER JOIN tableC
ON tableA.id = tableC.id
I have two tables. One is books table. It has two columns. id|title. Another is student_books table. It has two columns student_id|book_id. When a student tries to read a book, I check the student_books table whether the student_id and the book_id matches or not. A student can buy multiple books so there may have multiple entries in student_books table. now I want to show the list of books based on popularity(that has maximum entries in student_books table) on a page. How should I write the SQL query?
You can join books table with student_books and order by count for each book
select b.*
from books b
left outer join student_books s
on b.id = s.book_id
group by b.id, b.title
order by count(s.student_id) desc;
SELECT b.id, b.title
FROM books b
LEFT JOIN students s ON s.book_id = b.id
GROUP BY b.id, b.title
ORDER BY COUNT(s.book_id) DESC;
I have a table for comments ("event_comments") to different events with the following columns:
post_id
event_id
username
comment
date
I want to be able to retrieve this info from the database and also be able to print the username, first name and last name; for this, I thought of using INNER JOIN, but it is not working for the following reason: I have 3 different profile types (3 different tables) "students", "guardians", "teachers" and when I try to use the INNER JOIN using "username" I get an error message saying that Column 'username' in from clause is ambiguous.
SELECT event_comments.post_id, event_comments.event_id, event_comments.username, event_comments.comment, event_comments.date,
students.first_name, students.last_name, students.picture,
guardians.first_name, guardians.last_name, guardians.picture,
teachers.first_name, teachers.last_name, teachers.picture
FROM event_comments
INNER JOIN students
INNER JOIN guardians
INNER JOIN teachers
USING (username)
ORDER BY date DESC
LIMIT 20
I tried to do this and it worked, but it only shows 1 comment per user; if the user has more than 1 comment then the info is ignored:
SELECT event_comments.post_id, event_comments.event_id, event_comments.username, event_comments.comment, event_comments.date,
students.first_name, students.last_name, students.picture,
guardians.first_name, guardians.last_name, guardians.picture,
teachers.first_name, teachers.last_name, teachers.picture
FROM event_comments
INNER JOIN students
INNER JOIN guardians
INNER JOIN teachers
GROUP BY username
ORDER BY date DESC
LIMIT 20
Does anybody how to get the INNER JOINs to work? is there a better way to do what I want? I hope I explained myself well.
Thanks!
do it like this:
SELECT event_comments.post_id, event_comments.event_id, event_comments.username, event_comments.comment, event_comments.date,
students.first_name, students.last_name, students.picture,
guardians.first_name, guardians.last_name, guardians.picture,
teachers.first_name, teachers.last_name, teachers.picture
FROM event_comments
INNER JOIN students
on event_comments.username=students.username
INNER JOIN guardians
on event_comments.username=guardians.username
INNER JOIN teachers
on event_comments.username=teachers.username
ORDER BY date DESC
LIMIT 20
This will work but assuming that a username from one table is not present in other tables, this will result into 0 rows.
a more logical approach would be to select each table then union it to join every result set like this :
SELECT e.post_id, e.event_id, e.username, e.comment, e_comments.date,
s.first_name, s.last_name, s.picture
from event_comments e
inner join students s
on e.username=g.username
UNION SELECT e.post_id, e.event_id, e.username, e.comment, e_comments.date,
g.first_name, g.last_name, g.picture
from event_comments e
inner join guardians g
on e.username=g.username
UNION SELECT e.post_id, e.event_id, e.username, e.comment, e_comments.date,
t.first_name, t.last_name, t.picture
from event_comments e
inner join teacher t
on e.username=t.username
EDIT:
To explain better about the query it just does this simple steps:
Query all comments from students using username to join post to students
Query all comments from guardians using username to join post to guardians
Query all comments from teachers using username to join post to teachers
Join results from students,guardians, teachers together
You need the using clause for each pair of joins:
FROM event_comments INNER JOIN
students
USING (username) INNER JOIN
guardians
USING (username) INNER JOIN
teachers
USING (username)
In MySQL, an inner join with no on clause is treated as a cross join. In other databases, an on or using clause is required for an inner join.
i'm working with php mysql and there are 12 tables which contains student informations.There are 3 main table First table is registration, second is demandraft and third is creditcard.The demandraft table contains all the creditcard table fields but as empty. now i want to get the whole data from these three tables to generate my xls file but coz there are empty fields of creditcard table in demandraft table so unable to fetch the whole records from all 3 tables. there is stuid field common in all 3 tables.
Here is my join query for that:
$sql = "select * from registration
join programme on registration.id=programme.stuid
join family on registration.id=family.stuid
join address on registration.id=address.stuid
join education on registration.id=education.stuid
join extradetail on registration.id=extradetail.stuid
join workexperience on registration.id=workexperience.stuid
join demanddraft on registration.id=demanddraft.stuid
join payonline on registration.id=payonline.stuid
where (DATE(registration.createddate)>='".$term1."'
AND DATE(registration.createddate)<='".$term2."')";
Use a left join.
select *
from a join b on a.id = b.a_id
will not list lines of table a that do not appear in table b.
select *
from a left join b on a.id = b.a_id
will.
Left join might be a bit tricky when chaining many of them with multiple tables. You may have to cleverly use parentheses around joins such that the order of joins is correct.
This :
$sql = "select * from registration
left join programme on registration.id=programme.stuid
left join family on registration.id=family.stuid
left join address on registration.id=address.stuid
left join education on registration.id=education.stuid
left join extradetail on registration.id=extradetail.stuid
left join workexperience on registration.id=workexperience.stuid
left join demanddraft on registration.id=demanddraft.stuid
left join payonline on registration.id=payonline.stuid
where (DATE(registration.createddate)>='".$term1."'
AND DATE(registration.createddate)<='".$term2."')";
Should do the trick
I am building a blog with Codeigniter and MySQL. The question I have is this, I have a table with posts and one with categories. I also have a cross reference table with post_categories. What I am trying to do is get all the categories with their names and the number of posts they have under their name.
Example output would be: Hello World(1) Test(0) etc.
What I am having a hard time finding is a SQL query that will join the three tables and get me the counts, and I am also having a hard time wrapping my head around how to make that query.
Here is my table schema:
blgpost
====
id
*Other schema unimportant
blgpostcategories
=================
postid
categoryid
blgcategories
==========
id
name
*Other schema unimportant
This should give you the output you want....
SELECT c.name, COUNT(p.id) FROM
blgcategories c
INNER JOIN blgpostcategories pc ON c.id = pc.categoryid
INNER JOIN blgpost p ON pc.postid = p.id
GROUP BY c.id
You don't need to join the three tables - the blgpost table doesn't have any information in it that you need.
SELECT COUNT(*), blgcategories.name
FROM blgcategories INNER JOIN blgpostcategories
ON blgcategories.id=blgpostcategories.categoryid
GROUP BY blgcategories.id;
SELECT name, COUNT(pc.id)
FROM blgcategories c
LEFT JOIN
blgpostcategories pc
ON pc.categoryid = c.id
GROUP BY
c.id
Using LEFT JOIN will show 0 for empty categories (those without posts linked to them) rather than omitting them.