I have a bills table with column customer_type and customer_id fields.
This customer_type tells if the customer is in the customers table or in the users table or in the suppliers table.
I need to create a query with left join according to customer_type.
select c.* from bills b
left join ***b.customer_type*** c on c.id = b.customer_id
You could join all three with necessary condition:
select c.*, u.*, s.* from bills b
left join customers c on c.id = b.customer_id and b.customer_type = 'customers'
left join users u on u.id = b.customer_id and b.customer_type = 'users'
left join suppliers s on s.id = b.customer_id and b.customer_type = 'suppliers'
Then you can take the data that is relevant from the result.
However if there are similar columns in these 3 tables you might want to restructure the database to only store one type of information in one place.
Related
I have a table with persons (personid,name), another table with camps (campid,title) and a third table with camp participations (id,personid,campid).
Now, for a given camp, I need a list of all other camp participations by all persons participating in the current camp.
But I have no idea how to join these tables. I have looked at a lot of other examples, but I can't really seem to get any inspiration from those...
This should work:
SELECT *
FROM PERSONS AS D INNER JOIN CAMP_PARTICIPATIONS AS E ON D.PERSONID = E.PERSONID
INNER JOIN CAMPS AS F ON F.CAMPID = E.CAMPID
WHERE F.CAMPID <> [your_camp] AND A.PERSONID IN (
SELECT A.PERSONID
FROM PERSONS AS A INNER JOIN CAMP_PARTICIPATIONS AS B ON A.PERSONID = B.PERSONID
INNER JOIN CAMPS AS C ON C.CAMPID = B.CAMPID
WHERE C.CAMPID = [your_camp] )
select persons.*,participations.*,camps.* from persons left join participations
on participations.personid=persons.personid
left join camps on camps.campid=participations.campid
where camp.campid=1;
now u can change the campid in where clause and place column name which u want in select clause
I am struggling to get this query to work . I have three tables and I want to do a query to get the red area.
Each circle is a table with different structure. I have managed a lot of combinations of inner joins but i specially cant get all the red areas.
A Payments : idPayment , idInvoice , Amount , date.
B Invoice : idInvoice , amount date.
C PromissoryNotes: IdNote , idInvoice, amount, date.
so far ...
SELECT B.idInvoice,A.idPayment,C.idNote FROM (Invoice b INNER JOIN payments a ON a.idInvoice=b.idInvoice) LEFT OUTER JOIN PromissoryNotes c ON c.idInvoice=b.idInvoice ORDER BY idInvoice.
DOESNT QUITE WORK
Any suggestions?
You were pretty close -- another OUTER JOIN and some WHERE criteria will do the trick:
SELECT B.idInvoice, A.idPayment, C.idNote
FROM Invoice b
LEFT JOIN payments a ON a.idInvoice=b.idInvoice
LEFT JOIN PromissoryNotes c ON c.idInvoice=b.idInvoice
WHERE a.idInvoice IS NOT NULL
OR c.idInvoice IS NOT NULL
ORDER BY B.idInvoice
What this basically says is give me all results from table B, where there's a match in table a or table c.
Condensed SQL Fiddle Demo
You could do this two ways:
1) Create a set A that is the inner join of B and A, create a set C that is the inner join of B and C, then union A and C.
2) Create a sub query that inner joins A and B, then full outer join to a sub query that inner joins C and B.
Example of 1)
SELECT b.idInvoice FROM Invoice B
JOIN Payments A on A.IdInvoice = B.IdInvoice
UNION
SELECT b.idInvoice FROM Invoice B
JOIN PromissoryNotes C on c.idInvoice = B.id Invoice
Example of 2)
SELECT idInvoice FROM
(
SELECT b.idInvoice FROM Invoice B
JOIN Payments A on A.IdInvoice = B.IdInvoice
) B FULL OUTER JOIN
(
SELECT b.idInvoice FROM Invoice B
JOIN Payments A on A.IdInvoice = B.IdInvoice
) C on b.idInvoice = C.idInvoice
Try
SELECT B.idInvoice, A.idPayment, C.idNote FROM Invoice B INNER JOIN payments A ON A.idInVoice = B.idInvoice INNER JOIN PromissoryNotes C ON C.idInvoice = B.idInvoice ORDER BY idInvoice
INNER JOIN means you get the intersection of both tables. So this is what you want.
Does this do the trick?
SELECT
ZZ.idInvoice,
ZZ.idPayment,
YY.idInvoice,
YY.idNote
FROM
(SELECT idInvoice, idPayment
FROM Invoice b
INNER JOIN payments a ON a.idInvoice=b.idInvoice) AS ZZ
FULL OUTER JOIN
(SELECT idInvoice, idNote
FROM PromissoryNotes c
INNER JOIN payments a ON a.idInvoice=c.idInvoice) AS YY ON ZZ.idInvoice = YY.idInvoice
SELECT p.idInvoice, p.idPayment, idNote
FROM Payments p JOIN Invoice i ON p.adInvoice-i.adInvoice RIGHT OUTER JOIN PromissoryNotes
UNION
SELECT i.idInvoice, idPayment, idNote
FROM Invoice i JOIN PromissoryNotes pn ON i.idInvoice=pn.idInvoice RIGHT OUTER JOIN Payments
You need to include the outer joins because the resulting tables that are to be unioned must have the same schema. I believe these are the desired fields from the query.
Maybe there's a better way to do this... I have a table of member friend requests. The columns are request_id, author_id, recipient_id, status(accepted or denied). I also have a members table whose id is linked to the author or recipient. I want to get a list of a member's friends by selecting from the members table and then joining the requests table. Since the member can be either the author or the recipient of any, some, or none of the requests, a simple LEFT JOIN member_requests AS r ON member_id = r.author_id wouldn't work. How can I write a query that will do this?
SELECT
m.member_id, m.display_name
r.author_id, r.recipient_id, r.status
FROM members AS m
LEFT JOIN member_requests AS r ON m.member_id = r.recipient_id
WHERE r.status = 1 --Accepted
ORDER BY m.display_name
You can use an OR in your left join, like so:
LEFT JOIN member_requests AS r
ON m.member_id = r.recipient_id
OR m.member_id = r.author_id
However, your where clause also needs to be altered:
SELECT
m.member_id, m.display_name
r.author_id, r.recipient_id, r.status
FROM members AS m
LEFT JOIN member_requests AS r
ON (m.member_id = r.recipient_id
OR m.member_id = r.author_id)
AND r.status = 1 //Accepted
ORDER BY m.display_name
When you left join table A to table B, and then specify a restriction in your where clause on table B, you convert your left join into an inner join. Typically, a left join to table B would yield some null values, since table A might have records that don't join to table B. But if you say 'where table B.value = x', you restrict your join to only rows in which table A joins to table B, and furthermore to rows in which 'B.value = x'. The join is then evaluated as an inner join, rather than a left outer.
Is it possible to INNER JOIN a MySQL query to achieve this result?
I have a table with Strategies and a table with Members. The Strategy table holds the ID of the author that corresponds to their ID in the Member table and the ID of an author that updated the existing author's work. Is it possible to grab a reference to both of these people at the same time? Something like the following, which returns no errors, but also no results...
SELECT * FROM Strategies
INNER JOIN Members AS a
INNER JOIN Members AS b
WHERE Strategies.ID='2'
AND Strategies.AuthorID = a.ID
AND Strategies.UpdateAuthorID = b.ID
Use a LEFT JOIN:
SELECT
s.*,
a.Name AS MemberName,
b.Name AS UpdatedMemberName
FROM Strategies AS s
LEFT JOIN Members AS a ON s.AuthorID = a.ID AND s.ID = 2
LEFT JOIN Members AS b ON s.UpdateAuthorID = b.ID AND s.ID = 2 ;
If you want them in one column use COALESCE:
SELECT
s.*,
COALESCE(a.Name, b.Name) AS MemberName
FROM Strategies AS s
LEFT JOIN Members AS a ON s.AuthorID = a.ID AND s.ID = 2
LEFT JOIN Members AS b ON s.UpdateAuthorID = b.ID AND s.ID = 2
SELECT toD.dom_url AS ToURL,
fromD.dom_url AS FromUrl,
rvw.*
FROM reviews AS rvw
LEFT JOIN domain AS toD
ON toD.Dom_ID = rvw.rev_dom_for
LEFT JOIN domain AS fromD
ON fromD.Dom_ID = rvw.rev_dom_from
if domain is table name
I have a users table which contains the users information (fname, lname...etc) and a invoices table. In the invoices table I have a field called created_id which links to the user.id that created the invoice. I also have a field called staff_id which links to the staff user.id that approved the invoice.
How can I query the first and last name for both the created_id and the staff_id in a single query? Here are a few things I've tried....
SELECT
invoices.*,
users.fname as created_fname,
users.lname as created_lname
FROM
invoices
INNER JOIN users
ON users.id = invoices.created_id;
This works, but it only gets me the person's name that created the invoice. How can I add the staff's name to that as well....
SELECT
invoices.*,
users.fname as created_fname,
users.lname as created_lname,
users2.fname as staff_fname,
users2.lname as staff_lname
FROM invoices, users
LEFT JOIN
invoices,
users AS users2
ON
users.id = invoices.created_id,
users.id = users2.id
That doesn't work, but is closer. Any guidance or examples would be very helpful. Also, if you have any recommendations for good books on learning how to do more advanced MySQL queries that would be helpful too.
You need to join users table twice on table Invoice.
SELECT a.*,
b.fname created_firstName,
b.lname created_LastName,
c.fname staff_firstName,
c.lname staff_LastName
FROM Invoice a
INNER JOIN users b
ON a.created_id = b.id
INNER JOIN users c
ON a.staff_id = c.id
and best thing is you can concatenate their names into one using CONCAT
SELECT a.*,
CONCAT(b.fname, ' ', b.lname) created_fullName,
CONCAT(c.fname, ' ', c.lname) staff_fullName
FROM Invoice a
INNER JOIN users b
ON a.created_id = b.id
INNER JOIN users c
ON a.staff_id = c.id