Left Join? zeros are not returned - mysql

I have been trying to get the result of this query to include all the flavor.model and sum the quantity of the ones ordered. It does work except it does not show anythign from the flavor table when nothing was ordered. I though left join would include all the item from the left side?
select
flavor.id,
flavor.model,
IFNULL(SUM(orders.quantity),0)as ORDERED
from
orders
LEFT JOIN
flavor
ON orders.model=flavor.model
where
orders.orddate >= '131006'
and orders.orddate <= '131013'
and orders.buyer<>'****#gmail.com'
GROUP BY
flavor.model

You might want to do a RIGHT JOIN instead of a LEFT JOIN as your left column, orders is your reference table, hence you won't get flavour values which aren't found.

Related

MYSQL join on multiple criteria not working

I have a query which uses LEFT JOIN with multiple criteria to fetch the data. However, the query does not return any data when I use more than one AND clause in the conditions.
Eg:
LEFT JOIN tblName
on x.ABC=y.ABC
AND x.MNO="AnyValue"
AND x.UserId=1
does not return any data.
However when I remove the last AND clause (i.e LEFT JOIN tblName on x.ABC=y.ABC AND x.MNO="AnyValue"), it gives me wrong result. But yes it atleast return some data.
Let me know how to add multiple conditions to get the query working.
I want to get results using the above first condition, i.e LEFT JOIN tblName on x.ABC=y.ABC AND x.MNO="AnyValue" AND x.UserId=1
Your AND ... criteria needs to be in the WHERE part of the query.
First, lets make sure you understand what a LEFT JOIN is. Try to think of it this way. The left side is how I think in the sequential order of the FROM clause. You read left-to-right, so the first table is my LEFT side which is what I ALWAYS want. The right side (next table in the query) is optional, but if it exists, great, I have more detail.
So take a scenario of people and orders. I want a list of all people. But if they have an order, thats even better.
select
P.LastName,
O.OrderID,
O.OrderDate
from
People P
LEFT JOIN Order O
on P.PersonID = O.PersonID
This will do just that. Show all people and IF they have an order, that comes along for the ride. If they have multiple orders, it will show a row for ALL orders they had.
Now, expand on criteria to the next table. Lets say I only wanted to show orders since 2018. That would become part of the LEFT JOIN "ON" clause because I only care about orders portion of the requirement.
LEFT JOIN Order O
on P.PersonID = O.PersonID
AND O.OrderDate >= '2018-01-01'
I would still get ALL people, but only order info will show for those with an order date on/after Jan 1, 2018.
Now, if you only cared about ONLY PEOPLE who HAD ORDERS AND the orders were on after 2018, that would basically eliminate the need for a LEFT JOIN and become a standard (INNER) JOIN
JOIN Order O
on P.PersonID = O.PersonID
AND O.OrderDate >= '2018-01-01'
JOIN Implies the record in the ORDER side table MUST be found
So in your scenario, where is your "x" and "y" alias name coming from. Completely unclear given the context, but hopefully the above clarification will help you resolve your query. If not, update it with more detail and clarification what you are trying to get out of it.

mysql join Get unjoined values too

The below query is based on my payments table. which joins with daily orders table. I have list of bill numbers in my daily table. with this query I get only bill number for which the payment has been made. Would like to get the complete list of bill numbers from daily table and if payment not received then the received column to be empty.And order them with Bill-no Ascending
create or replace view view_pymts
As SELECT p.`order-id`, p.`order-item-code`,daily.Bill_no,daily.tally_sku,daily.`quantity-purchased` as quantity,daily.`item-price`+daily.`shipping-price`as inv_value,daily.rma_rcvd_amt as return_value, round((SUM(p.amount) + z.other),2) AS received
FROM payments p
INNER JOIN daily ON p.`order-item-code`= daily.`order-item-id`
JOIN (
SELECT `order-id`,
SUM(CASE WHEN `order-item-code` IS NULL
THEN amount
ELSE 0.0 END) / (COUNT(DISTINCT `order-item-code`)) AS other
FROM payments
GROUP BY `order-id`
) z
ON p.`order-id` = z.`order-id`
GROUP BY p.`order-id`, p.`order-item-code`
Replace INNER JOIN with LEFT JOIN. This will make all missing fields NULL in the table on the right of the join (the table after the join statement, rather than the one before, which is said to be on the left of the join).
EDIT: I didn't read the question carefully enough, and #minatverma is correct. You could either use a RIGHT JOIN in place of your INNER JOIN (right join doing the opposite of a left join, making null the fields missing in the table on the left), or switch the order of your tables and use a LEFT JOIN.

AVG + Inner join

I'm trying to make something like a chart list and my actual query is like this:
SELECT
user.username,
songs.*,
albums.desc,
albums.release,
albums.name,
AVG(songrating.rating)
FROM
songs
INNER JOIN
user
ON
songs.userid=user.id
INNER JOIN
albums
ON
songs.albumid=albums.id
INNER JOIN
songrating
ON
songs.id=songrating.songid
GROUP BY
songrating.songid
it only shows entries with at least one rating entry, but I also want these without a rating
I tried to use it with if / case but it doesn't work (or I'm doing something wrong)
If I remove the avg etc, it works correctly.
It may be JOIN issue
The INNER JOIN keyword selects all rows from both tables as long as there is a match between the columns in both tables.
The LEFT JOIN keyword returns all rows from the left table (table1), with the matching rows in the right table (table2). The result is NULL in the right side when there is no match.
Try LEFT JOIN

Left outer join and sum issue

I need a query. I'm trying to sum of one field with joined tables. Some records not in second table. So this records sum should be zero. But the query only sum the records which are in the second table.
select s.*,sum(sd.fiyat) as konak from fuar_sozlesme1 s
left outer join fuar_sozlesme1_detay sd on (sd.sozlesme_id = s.id)
------EDIT-------
I added group by into the query and solved my problem. Here is the new ;
select s.*,sum(sd.fiyat) as konak from fuar_sozlesme1 s
left outer join fuar_sozlesme1_detay sd on (sd.sozlesme_id = s.id)
group by sd.sozlesme_id
I thinik you need to use IFNULL(sd.fiyat,0) instead of sd.fiyat to get zeros for the NULL values coming from the second table because of the LEFT JOIN like so:
SELECT s.*, SUM(IFNULL(sd.fiyat, 0)) as konak
FROM fuar_sozlesme1 s
LEFT OUTER JOIN fuar_sozlesme1_detay sd ON sd.sozlesme_id = s.id
GROUP BY s.someFields
Here is a simple example, you may help: http://sqlfiddle.com/#!2/41481/1
This is an old thread, but I spent a couple of hours trying to solve the same issue.
My query has two joins, a filter and a SUM function. I'm no SQL expert, but this helped me achieve the desired result of still showing a result even if the joined table had no rows to sum.
The key for me in order to show results even if the sum was totaling nothing, was the GROUP BY. I'm still not 100% sure why.
The two types of joins were chosen based on this article - MySQL Multiple Joins in one query?
SELECT registrations.reg_active, registrations.team_id, registrations.area_id, registrations.option_id, registrations.reg_fund_goal, registrations.reg_type, registrations.reg_fee_paid, registrations.reg_has_avatar, users.user_name, users.user_email, users.user_phone, users.user_zip, users.user_age, users.user_gender, users.user_active, SUM(IFNULL(donations.donation_amount,0)) as amt from registrations
INNER JOIN `users`
ON registrations.user_id = users.user_id
AND registrations.event_id = :event_id
LEFT OUTER JOIN `donations`
ON registrations.reg_id = donations.reg_id
GROUP BY donations.reg_id
ORDER BY users.user_name ASC

MySQL - How to JOIN with an unexisting index?

I have a table in my DB called ORDERS and it looks like this:
ID_section (int), ID_price (int), ID_city (int), ID_company (int)
And I want to use the JOIN method to set names to the ID's.
What I would do is:
SELECT * FROM ORDERS
JOIN sections ON sections.id=orders.ID_section
JOIN prices ON prices.id=orders.ID_price
JOIN cities on cities.id=orders.ID_cities
JOIN companies ON companies.id=orders.ID_company
But the point is, that in ORDERS table can be inserted value of 0 and it means - all the sections/prices/cities/companies, but when I run my query, only the values, that their ID exist in the other table show up.
Any ideas? Thanks.
If I understand you question correctly and having, for example, ID_section = 0 means that the order belongs to all the section then the following query should do the trick.
SELECT * FROM ORDERS
JOIN sections ON sections.id=orders.ID_section OR orders.ID_section = 0
JOIN prices ON prices.id=orders.ID_price OR orders.ID_price = 0
JOIN cities on cities.id=orders.ID_cities OR orders.ID_cities = 0
JOIN companies ON companies.id=orders.ID_company OR orders.ID_company = 0
If, on the other hand, you want to retrieve all orders regardless if they have sections, prices, etc. associated, then it is sufficient to put LEFT JOIN where you have JOIN. (But this situation does not result from your question! I only added it because people seem to understand that.)
Use LEFT JOIN instead of JOIN (which is a shorthand for INNER JOIN)
Experiment with LEFT and RIGHT OUTER JOIN s and you'll be able to figure out what you need to do. Basically a LEFT or RIGHT OUTER JOIN will insert NULLS into columns where no data exists but still do the joins.
There are various resources on the web that explain this.