mySQL union allow for non match - mysql

I am trying to write a query that will pull some product information AND photos, if the product has any.
select
prod.pID, prod.Manufacturer_Name, prod.pUPC, prod.pNum, prod.pPrice, prod.pSalesPrice, prod.pSalesDate, prod.pSalesEndDate, prod.pSale,
GROUP_CONCAT(photoName) as photos
from
ds_products as prod
inner join ds_photos as pics on pics.objectID=prod.pID
where
pics.photoFlag =2
group by
prod.pID
The problem with this is that products that do not have photos get left out of the result set. What do I need to add and/or change to allow for a product that doesn't appear in the photos table to show up in the results?
Thanks
EDIT
I tried the LEFT JOIN instead of inner but get the same result set. If i run just:
select
prod.pID, prod.Manufacturer_Name, prod.pUPC, prod.pNum, prod.pPrice, prod.pSalesPrice, prod.pSalesDate, prod.pSalesEndDate, prod.pSale
from
ds_products as prod
I get about 600k results. The inner and or left join queries get about 190k results. Is there another way to do this?

Use outer join
select
prod.pID, prod.Manufacturer_Name, prod.pUPC, prod.pNum, prod.pPrice, prod.pSalesPrice, prod.pSalesDate, prod.pSalesEndDate, prod.pSale,
GROUP_CONCAT(photoName) as photos
from
ds_products as prod
LEFT join ds_photos as pics on pics.objectID=prod.pID
where
pics.photoFlag =2 OR pics.photoFlag is NULL
group by
prod.pID
I have added a condition which check if photoFlag is null for the products which don't have corresponding pics
Here is working fiddle : http://sqlfiddle.com/#!2/c2a9c/1/0
For more information: http://dev.mysql.com/doc/refman/5.0/en/outer-join-simplification.html

You need to use a LEFT JOIN instead of INNER JOIN like this
select
prod.pID, prod.Manufacturer_Name, prod.pUPC, prod.pNum, prod.pPrice, prod.pSalesPrice, prod.pSalesDate, prod.pSalesEndDate, prod.pSale,
GROUP_CONCAT(photoName) as photos
from
ds_products as prod
LEFT JOIN ds_photos as pics on pics.objectID=prod.pID
group by
prod.pID
Note I have also removed your where clause, as this was looking for a value in pics table that would restrict the result set.

Related

Left join with calculated column and different schemas?

I would like to perform a left join on the following tables:
Vehicles.boats,
vehicle_details.colors
With columns
vehicles.boats.yacht
color_id
where color_id is computed from vehicle_details.colors in a calculation that involves
vehicle_details.colors.sequence
and
vehicle_details.colors.name
I assume the following would serve as my skeleton, but I am unsure of where to put the calculations that define color_id:
SELECT vehicles.boats.yacht, vehicle_details.colors.sequence
FROM vehicles.boats
LEFT JOIN vehicle_details.colors
ON vehicle.boats.colorIdentifier = color_id;
Would it be something like the following, where the calculation is used in the ON portion?
SELECT vehicles.boats.yacht, vehicle_details.colors.sequence
FROM vehicles.boats
LEFT JOIN vehicle_details.colors
ON vehicle.boats.colorIdentifier = *calculations* AS color_id;
In that format you need to do the calculation twice, once for the join condition, once for the display.
SELECT vehicles.boats.yacht, vehicle_details.colors.sequence,*calculations* AS color_id;
FROM vehicles.boats
LEFT JOIN vehicle_details.colors
ON vehicles.boats.colorIdentifier = *calculations*;
You could use a subquery and do it once, something like:
SELECT vehicles.boats.yacht, vehicle_details.colors.sequence, color_id;
FROM vehicles.boats
LEFT JOIN ( Select vehicle_details.colors, *calculations* as colour_id from vehicle_details) as Details_subquery
ON vehicles.boats.colorIdentifier = colour_id ;

Multiple Inner join blank result without error

Hi dev's i'm new with "advanced" SQL I've try alone but I dont understand how to have the good result.
I'll try to take information from 4 tables in the same DB.
The first table items only have id and name.
2 others tables take the id from items to extract data.
The last tables takes one data from items_buy for print another data.
Lastly I concat 2 column from 2 DB for having a full information.
SELECT items.id, items.name, items_buy.item_cost AS item_cost, items_sales.item_price AS item_price, CONCAT(trader.name, planet.name) AS name_point
FROM ((((items
INNER JOIN items_buy ON items_buy.id = items.id)
INNER JOIN trader ON trader.id = items_buy.name_point)
INNER JOIN items_sales ON items_sales.id = items.id)
INNER JOIN planet ON planet.id = trader.planet)
WHERE items.id = 1;
I dont know how to make it work, she doesnt return an error in SQLyog or on my server.
In order:
ID / NAMEITEM / PRICE / SELLINGPRICE / NAME from concat
If you need more, some test data:
https://pastebin.com/6Bs4kbN9
I've run your test data and run your script against it. As I suggested in my commment, the problem is with the INNER JOIN you are using.
I am not sure whether you are aware, but when using an INNER JOIN, if the joined table is NULL for the current row, then nothing at all will be returned.
If you modify your query to use a LEFT JOIN, you will see the results that are available regardless of whether the joined tables are NULL or otherwise:
SELECT items.id, items.name, items_buy.item_cost AS item_cost, items_sales.item_price AS item_price, CONCAT(trader.name, planet.name) AS name_point
FROM ((((items
LEFT JOIN items_buy ON items_buy.id = items.id)
LEFT JOIN trader ON trader.id = items_buy.name_point)
LEFT JOIN items_sales ON items_sales.id = items.id)
LEFT JOIN planet ON planet.id = trader.planet)
WHERE items.id = 1;
This produces:
1 Agricium 24.45 25.6 NULL
1 Agricium 24.6 25.6 NULL
The problem in the case of your example is that the join to trader or planet has no result and therefore produces no output.

inner and outer join together in query, possible

i am trying to implement inner and outer join in single query, i am not sure if i am doing the right way or wrong way, as i am not very good with queries.
So here it goes.
I have these following tables.
hrs_residentials
hrs_residential_utilities
hrs_utilities
hrs_utility_type
hrs_residentials:
ResID, ResType, ResNo - - -
1 2 001 - - -
hrs_residential_utilities:
RUID, UtilityID, ResID, - - - -
NULL NULL NULL
hrs_utilities:
UtilityID, UtilityTypeID, Number, ConsumerNumber, -, -, -
NULL NULL NULL NULL
hrs_utility_type:
UTID, UName, UDescription
1 PESCO PESCO Electric Meter
2 SNGPL Sui Northen Gas Pipe Lines
So i want to show in datatables the data, but what i want that data should show in table for hrs_residentials table, dosent matter if hrs_residential_utilities have data or not.
So i went for Left outer join and i got the result i wanted.
But after that when i tried to do inner for hrs_residential_utilities with hrs_utilities, i stopped getting results for hrs_residentials as well. As if we see hrs_residential do have the data inside table. I dont want inner join with hrs_residentials, i want to have inner join between hrs_residential_utilities and hrs_utilities.
Is it possible, or i am following the wrong approach here? Sorry i am not good. What will the Proper Query if anyone can help me with it.
This is the Query i have tried so far.
SELECT R.`ResID`,R.`ResNo`
FROM `hrs_residentials` R
LEFT OUTER JOIN `hrs_residential_utilities` RU
ON R.`ResID` = RU.ResID
INNER JOIN `hrs_utilities` U
ON RU.`UtilityID` = U.`UtilityID`
WHERE 1=1;
I stopped Getting Results from the hrs_residentials table After the Inner Join, but i am making Inner join between other two tables.
Try a subquery like this:
SELECT *
FROM `hrs_residentials` R
LEFT OUTER JOIN
(
SELECT * FROM
`hrs_residential_utilities` RU
INNER JOIN `hrs_utilities` U
ON RU.`UtilityID` = U.`UtilityID`
) AS subqyr
ON R.`ResID` = subqyr.`ResID`
run this query and view the results
SELECT R.ResID,R.ResNo
FROM hrs_residentials R
LEFT OUTER JOIN hrs_residential_utilities RU
ON R.ResID = RU.ResID
then run this query and view the results:
SELECT * FROM hrs_utilities
I suspect what you will find is that the RU.utilities ID does not match anything in the hrs_utilities.
Your query itself should return everything in hrs_residentials and join on any matching data from hrs_residential_utilities this may or may not return RU.ResID as null depending on whether it can match.
It then filters on whether RU.UtilityId matches with anything in the hrs_utilities table, this won't match on null items.
Thanks.
oliver

Adding one JOIN statement changes the value of precedent sum

I have this query in sqlfiddle which gives the correct values
But when I add one left joined table the result changes(I tried with right and inner join same bad result) and it's there in this sqlfiddle
What I miss in this query when adding stockdata?
There is 3 tables defmatiere, ingredients and stockdata
When I use this query:
SELECT dm.nom,SUM(IF(dm.id=ig.matid AND ig.matcuisine= 3,ig.qty,0)) AS bisused
FROM ingredient AS ig
LEFT JOIN DefMatiere AS dm ON ig.matid=dm.id AND ig.matcuisine=3
WHERE dm.id=ig.matid AND dm.type=1 GROUP BY dm.nom
I get the corrects sums
But When I use this query
SELECT dm.nom,SUM(IF(dm.id=ig.matid AND ig.matcuisine= 3,ig.qty,0)) AS bisused,
SUM(DISTINCT IF(dm.id=sd.matid, sd.quantite,0)) AS bisbought
FROM ingredient AS ig
LEFT JOIN DefMatiere AS dm ON ig.matid=dm.id AND ig.matcuisine=3
LEFT JOIN StockData AS sd ON sd.matid=dm.id
WHERE dm.id=ig.matid AND dm.type=1 GROUP BY dm.nom
The sum of bisused is doubled the rest is correct

MySQL include zero rows when using COUNT with GROUP BY

I am trying to perform a query which groups a set of data by an attribute called type_id.
SELECT
vt.id AS voucher_type,
COALESCE(COUNT(v.id), 0) AS vouchers_remaining
FROM
vouchers v
INNER JOIN voucher_types vt
ON vt.id = v.type_id
WHERE
v.sold = 0
GROUP BY vt.id
What I want in the result is the type_id and the number of unsold products remaining for each type. This is working OK provided that there is at least one left, however if there is a zero count row, it is not returned in the result set.
How can I set up a dummy row for those types which do not have any corresponding rows to count?
Any advice would be greatly appreciated.
Thanks
You'll have to use a LEFT JOIN instead of an INNER JOIN. You start by selecting all voucher_types and then left join to find the count.
SELECT
voucher_types.id AS voucher_type,
IFNULL(vouchers_count.vouchers_remaining, 0) AS vouchers_remaining
FROM
voucher_types
LEFT JOIN
(
SELECT
v.type_id AS voucher_type,
COUNT(v.id) AS vouchers_remaining
FROM
vouchers v
WHERE
v.sold = 0
GROUP BY v.type_id
) AS vouchers_count
ON vouchers_count.voucher_type = voucher_types.id
You want an OUTER JOIN (or LEFT JOIN, same difference) instead of an INNER JOIN. That should already do the trick.
Because you're doing an INNER JOIN you automatically exclude types with no corresponding vouchers. You need a RIGHT OUTER JOIN.
Also, as far as I can remember, COUNT will always give you an integer, so there is no need for the COALESCE.
Good luck,
Alin