I have three tables, one with the information about the client (name, username), another table with the service performed to his car (points obtained from the service), service made) and one with the company, representing where the client works (name, location).
I'm trying to make a query to get together the company where the client works, the client himself and the sum of all the points obtained. I already tried several approaches, but all failed. I want to display the client information even if it doesn't have any points.
This is what I already tried
SELECT *FROM client c
INNER JOIN company b ON c.company_idcompany = b.idcompany
INNER JOIN (select sum(pointos) as pointos From services) d
SELECT *FROM client c
INNER JOIN company b ON c.company_idcompany = b.idcompany
INNER JOIN service d ON c.idclient = d.client_idclient
You need to LEFT JOIN on your aggregated query. If you INNER JOIN, it will only return rows that have an entry in services. Clients with no services won't be returned. Try this
SELECT *FROM client c
INNER JOIN company b ON c.company_idcompany = b.idcompany
LEFT JOIN (select client_idclient,sum(pointos) as pointos From services group by client_idclient) d on c.idclient=d.client_idclient
If you need a zero rather than NULLs you can use IFNULL to convert the sum of the points.
Please, provide some more table structure data (as create script for example).
I think the problem is that you have to use LEFT JOIN in the joining and you are not providing any "connection information" in the first query's second join statement.
Related
I have three tables, tblPresents, tblPresentsOrdered and tblPresentsDelivered.
What I want to do is sum up all the orders and deliveries for a given present ID, so I can tally up the total ordered and delivered and check for discrepancies.
So far I have the following:
$sql ='SELECT prsName, SUM(ordQuantity) AS qtyOrdered,
SUM(delQuantity) AS qtyDelivered
FROM tblPresentOrders
LEFT JOIN tblPresentDeliveries
ON tblPresentDeliveries.delPresent = tblPresentOrders.ordPresent
RIGHT JOIN tblPresents ON tblPresents.prsID = tblPresentOrders.ordPresent
GROUP BY prsName';
The first column (Ordered) is summing up correctly, but the deliveries is counting the delivery twice (there are two separate orders for that line).
What am I doing wrong?
Because you can have multiple orders per delivery (and presumably multiple presents per order) you need to perform aggregation in derived tables before JOINing to avoid duplication in counted/summed values. Note that using a mixture of LEFT JOIN and RIGHT JOIN in the same query can be a bit hard to read so I've rewritten the query using only LEFT JOINs.
SELECT p.prsName, o.qtyOrdered, d.qtyDelivered
FROM tblPresents p
LEFT JOIN (SELECT ordPresent, SUM(ordQuantity) AS qtyOrdered
FROM tblPresentOrders
GROUP BY ordPresent) o ON o.ordPresent = p.prsID
LEFT JOIN (SELECT delPresent, SUM(delQuantity) AS qtyDelivered
FROM tblPresentDeliveries
GROUP BY delPresent) d ON d.delPresent = p.prsID
I am developing a networking site where I have to show random users profiles (excluding members who are already connected) to logged-in user to connect with. I have one members table which contains fields as memberid,firstname and lastname. I have another table for connections which has fields as memberid and friendid.
Now when I use left join on connections table, I get profiles of only connected members which I dont want. I only want to show profiles form members table which are not connected with logged-in user
You can achieve this without Join with the use of Not in.
select *from
members
where
members.memberid not in (select memberid
from connections
)
;
The above query simply means to display info of memberids that are not in connections.
EDIT:
Since you've already used Left join. here is the query to achieve this task with Left join:
select m.*
from members m
left join connections c
on m.id = c.id
where c.id is null;
Hope it helps!
I have 3 tables offers countries and transactions and what I'm trying to do is extract the offers from a specific country and devices, I already do this with this formula:
SELECT
*
FROM countries a
INNER JOIN offers b ON a.id = b.offer_id
WHERE a.country = "US"
AND b.device = 'all'
UNION
SELECT
*
FROM countries a
INNER JOIN offers b ON a.id = b.offer_id
WHERE a.country = "US"
AND b.device LIKE 'iphone%';
This code works but now I want to exclude the offers with the same ref between the tables users and transactions
the way this should work is:
The user from X country enter on Y device.
The user select an offer according to his country and device.
The offer is registered via post back to transactions.
The user enter to the main page and not longer see the offer he already finish.
Right now i'm capable of do the 3 first steps but not the fourth step. Any help about how do this?
Here is an example of the tables: SQL Fiddle
Thanks in advance
EDIT
if I put all this on words would be something like:
Select all from *offers* where the **offer_id** match with **ID** from *countries* with the **country** "US" and also from *offers* have the **device** "iPhone" now exclude from *transactions* the offers with the **user** = "xxxxx"
I hope this explain a little bit what I'm trying to do
Can't see how the query is user-specific , but to exclude offers refered to from transactions you can use NOT EXISTS
SELECT *
FROM countries a
INNER JOIN offers b ON a.id=b.offer_id
WHERE a.country="US" AND b.device = 'all'
AND NOT EXISTS (SELECT 1 FROM transactions t WHERE t.offer = b.offer_Id)
You could solve it with a LEFT OUTER JOIN to the transactions table.
I added t.id IS NULL to the WHERE-clause. So your result will just display offers which have no transaction.
SELECT *
FROM countries a
INNER JOIN offers b
ON a.id = b.offer_id
LEFT OUTER JOIN transactions t
ON t.id = b.offer_id
WHERE a.country = "US"
AND t.id IS NULL
Regarding your question it is still unclear for me how the tables users & countries are connected. This is an important detail, as the LEFT OUTER JOIN should just grab transactions from this specific user. So the condition transactions.user = user.ref should be added to the join too.
Will update the answer whenever you explain me this link
Ok, I have a slightly complicated MySQL query
SELECT
childcare_attendance.supplier_id,
suppliers.name As `Childcare Provider`,
Count(families.ufi) As Attended,
families.ufi
FROM
childcare_attendance
LEFT OUTER JOIN
suppliers ON suppliers.id = childcare_attendance.supplier_id
LEFT OUTER JOIN
clients ON childcare_attendance.client_id = clients.id
LEFT OUTER JOIN
families ON clients.family_id = families.id
WHERE
childcare_attendance.trashed <> 1
GROUP BY
childcare_attendance.supplier_id, families.ufi
My issue is I want to create a report that lists the number of unique families that are attending each of the childcare places. I assumed that the above query would perform the task, although the childcare providers are showing multiple times and I am unsure why.
EDIT
Here is a SQL Fiddle without data (I will work on getting some test data in there)
http://sqlfiddle.com/#!9/7ef8e8
This is related to my other question:
Managing Foreign Keys
I am trying to join the table of matches and non-matches.
So I have a list of interests, a list of users, and a list of user interests.
I want the query to return all interests, whether the user has the interest or not (should be null in that case), only where the user = x. Every time I get the query working its only matching interests that the user specifically has, instead of all interests whether they have it or not.
You should rather use LEFT JOINS
Something like
SELECT *
FROM interests i LEFT JOIN
userinterests ui ON i.interestID = ui.interestID LEFT JOIN
users u ON ui.userID = u.uiserID
WHERE userID = ?
where is the user id you are looking for.
SELECT *
FROM interests i
LEFT JOIN userinterests ui ON i.interestID = ui.interestID
LEFT JOIN users u ON ui.userID = u.uiserID
and u.userID = ?
If you put a where condition on a table that should have no records inteh main tbale, you convert the join from a left join to an inner join. The only time you should ever have a condition inthe where clasue for something one the right side of a left join is when you are searching for records that don't match (where u.userid is null, for instance)
Of course you should define the fields to be selected and never use select * in production code especially not when you have a join as it sends repeated information across the network (the data inteh join feilds is repeated) and is a waste of resources and poor prgramming practice for multiple reasons.