mysql exclude results with same id in two tables - mysql

I have a working query that fetches some results.
$sql = "
SELECT
swdl.wedding_dress AS wedding_dress,
wd.name AS name,
wdi.url AS image
FROM salons_wedding_dresses_link AS swdl
LEFT JOIN wedding_dresses AS wd ON swdl.wedding_dress = wd.id
LEFT JOIN wedding_dress_images AS wdi ON wdi.wedding_dress = wd.id AND wdi.main_image = 1
WHERE swdl.salon = ? AND wd.active = 1
";
What i want is to update it to only fetch results where wedding_dress in table salons_wedding_dresses_link is not located in table wedding_dress_dress_collection_link in column wedding_dress_id but i fail to do so.
Bellow is the updated query, with update in bold.
$sql = "
SELECT
swdl.wedding_dress AS wedding_dress,
wd.name AS name,
wdi.url AS image
FROM salons_wedding_dresses_link AS swdl
LEFT JOIN wedding_dress_dress_collection_link AS wddcl
------------------------------------------------------
LEFT JOIN wedding_dresses AS wd ON swdl.wedding_dress = wd.id
LEFT JOIN wedding_dress_images AS wdi ON wdi.wedding_dress = wd.id AND wdi.main_image = 1
WHERE
swdl.wedding_dress NOT IN (SELECT wddcl.wedding_dress_id FROM wddcl) AND
------------------------------------------------------------------------
swdl.salon = ? AND wd.active = 1
";

select query to get the result which is present in salons_wedding_dresses_link but not in wedding_dress_dress_collection_link:
select s1.*,s2.wedding_dress_collection_id,s2.wedding_dress_id
from salons_wedding_dresses_link s1
left join wedding_dress_dress_collection_link s2 on
s1.wedding_dress=s2.wedding_dress_id
whrere s2.wedding_dress_id is null;

Related

MySQL: From sub query to a single query

I have this query which i believe can be optimized:
SELECT floors.id, floors.floor FROM floors
WHERE floors.societies_id = 1
AND floors.status = 'Y'
AND floors.id NOT IN (
SELECT DISTINCT(floors.id) FROM floors
INNER JOIN societies ON societies.id = floors.societies_id
INNER JOIN resident_floors ON resident_floors.floors_id = floors.id
WHERE societies.id = 1
AND floors.status = 'Y'
)
Is this query fine to use or there it can be improved..?
It looks like you want to get all floors that aren't present in resident_floors. For this we can left join RF in and ask for only rows where the join failed resulting in a null in RF:
SELECT floors.* FROM floors
INNER JOIN societies ON societies.id = floors.societies_id
LEFT JOIN resident_floors ON resident_floors.floors_id = floors.id
WHERE societies.id = 1
AND floors.status = 'Y'
AND resident_floors.floors_id IS NULL

Mysql Fetching rows base on date

Here's the code:
SELECT RD.INTREQDQUANTITY, I.strItemName, v.strVendName, iu.strItemUnitName,
ip.dblItemPAmount, MAX(ip.dtmItemPasOf) AS EXR
FROM TBLREQUESTDETAILS RD,tblitem I,tblvendor v,tblitemunit iu,tblitemprice ip`
WHERE RD.strReqDItemCode = I.strItemCode
AND RD.strReqDItemUnitCode = iu.strItemUnitCode
AND RD.strReqDVendCode = v.strVendCode
AND i.strItemCode = ip.strItemPItemCode
and RD.strReqDReqHCode = 'RQST121'
GROUP BY RD.INTREQDQUANTITY,I.strItemName,v.strVendName,iu.strItemUnitName, ip.dblItemPAmount
ORDER BY EXR desc ;
AND Here's The result:
What should I do If I want to fetch the current price for each itemname,vendorname and itemunit?? I want to fetch only those rows who's price is the Latest... Help me please those with boxes are the rows that i want to fetch
You can use where in the grouped value (and use explicict join notatio)
SELECT RD.INTREQDQUANTITY, I.strItemName, v.strVendName, iu.strItemUnitName,
ip.dblItemPAmount, ip.dtmItemPasOf AS EXR
FROM TBLREQUESTDETAILS RD
INNER JOIN tblitem I ON RD.strReqDItemCode = I.strItemCode
INNER JOIN tblvendor v ON D.strReqDVendCode = v.strVendCode
INNER JOIN tblitemunit iu ON RD.strReqDItemUnitCode = iu.strItemUnitCode
INNER JOIN tblitemprice ip ON i.strItemCode = ip.strItemPItemCode
WHERE RD.strReqDReqHCode = 'RQST121'
and ( RD.INTREQDQUANTITY, I.strItemName, v.strVendName, iu.strItemUnitName, ip.dtmItemPasOf)
in ( SELECT RD.INTREQDQUANTITY, I.strItemName, v.strVendName, iu.strItemUnitName,
MAX(ip.dtmItemPasOf)
FROM TBLREQUESTDETAILS RD
INNER JOIN tblitem I ON RD.strReqDItemCode = I.strItemCode
INNER JOIN tblvendor v ON D.strReqDVendCode = v.strVendCode
INNER JOIN tblitemunit iu ON RD.strReqDItemUnitCode = iu.strItemUnitCode
INNER JOIN tblitemprice ip ON i.strItemCode = ip.strItemPItemCode
WHERE RD.strReqDReqHCode = 'RQST121'
GROUP BY RD.INTREQDQUANTITY,I.strItemName,v.strVendName,iu.strItemUnitName
)
ORDER BY EXR desc ;
(and use explicict join notation .. i think is more readable)

MySQL LEFT JOIN example with conditions

I am using following query to retrieve the needed objects:
SELECT *
FROM tb_po_items
LEFT JOIN tb_materials ON tb_po_items.po_material = tb_materials.id_material
LEFT JOIN tb_services ON tb_po_items.po_service = tb_services.id_service
WHERE po_id =47
Now I need to add following:
Condition 1 -> if tb_po_items.mos = 1 then LEFT JOIN tb_units ON tb_materials.material_unit = tb_units.id_unit
else
Condition 2 -> if tb_po_items.mos = 2 then LEFT JOIN tb_units ON tb_services.service_unit = tb_units.id_unit
How can I implement the use of both conditions in the MySQL query?
Thanks in advance.
Try this:
SELECT *
FROM tb_po_items
LEFT JOIN tb_materials ON tb_po_items.po_material = tb_materials.id_material
LEFT JOIN tb_services ON tb_po_items.po_service = tb_services.id_service
LEFT JOIN tb_units ON (
(tb_materials.material_unit = tb_units.id_unit AND tb_po_items.mos = 1)
OR
(tb_services.service_unit = tb_units.id_unit AND tb_po_items.mos = 2) )
WHERE po_id =47;
hi this is experimental so check before you go live.
SELECT * FROM tb_po_items
IF(tb_po_items.mos = 1, LEFT JOIN tb_materials ON tb_po_items.po_material = tb_materials.id_material, LEFT JOIN tb_services ON tb_po_items.po_service = tb_services.id_service)
WHERE po_id =47

Mysql query with joined subqueries gives no result

i have a huge query:
SELECT stories.*
FROM stories stories
JOIN (SELECT tstories.uid
FROM stories tstories
JOIN tours_stories_mm mmt
ON tstories.uid = mmt.uid_foreign
JOIN tours tours
ON tours.uid = mmt.uid_local
JOIN tours_countries_rel tourcountryrel
ON tours.uid = tourcountryrel.tourid
JOIN countries tcountries
ON tcountries.uid = tourcountryrel.countryid
WHERE tcountries.uid = ?
AND tours.deleted = 0
AND tours.hidden = 0
AND tstories.deleted = 0
AND tstories.hidden = 0) as tourstories
JOIN (SELECT cstories.uid
FROM stories cstories
JOIN individualtourcomponents_stories_mm mmc
ON (cstories.uid = mmc.uid_foreign)
JOIN individualtourscomponents components
ON (components.uid = mmc.uid_local)
JOIN individualtourcomponents_countries_rel componentcountryrel
ON (components.uid = componentcountryrel.componentid)
JOIN countries ccountries
ON (ccountries.uid = componentcountryrel.countryid)
WHERE ccountries.uid = ?
AND components.deleted = 0
AND components.hidden = 0
AND cstories.deleted = 0
AND cstories.hidden = 0) as componentstories
WHERE stories.uid = componentstories.uid
OR stories.uid = tourstories.uid
GROUP BY stories.uid`
each of the subqueries work for themselves and if both subqueries have the same result, i get an result on the whole query. If only one subquery has a result i get nothing. Simplyfied it could be written like that:
SELECT stories.*
FROM stories
JOIN (SELECT * FROM table_a WHERE x=5) as table_a
JOIN (SELECT * form table_b where x=5) as table_b
WHERE stories.uid = table_a.uid OR stories.uid = table_b.uid
GROUP BY stories.uid
What am i doing wrong?
It seems like you should be using an OUTER JOIN instead of INNER JOIN to join your source tables.
Using the simplified query example, it might look like this:
SELECT stories.*
FROM stories
LEFT OUTER JOIN (SELECT * FROM table_a WHERE x=5) as table_a
ON stories.uid = table_a.uid
LEFT OUTER JOIN (SELECT * form table_b where x=5) as table_b
ON stories.uid = table_b.uid
GROUP BY stories.uid
UPDATE
Based on your comment it sounds like you actually want to get the distinct union of the the two sub queries.
If that's the case, you could modify your original query like this:
(SELECT tstories.*
FROM stories tstories
JOIN tours_stories_mm mmt
ON tstories.uid = mmt.uid_foreign
JOIN tours tours
ON tours.uid = mmt.uid_local
JOIN tours_countries_rel tourcountryrel
ON tours.uid = tourcountryrel.tourid
JOIN countries tcountries
ON tcountries.uid = tourcountryrel.countryid
WHERE tcountries.uid = ?
AND tours.deleted = 0
AND tours.hidden = 0
AND tstories.deleted = 0
AND tstories.hidden = 0
)
UNION DISTINCT
(SELECT cstories.*
FROM stories cstories
JOIN individualtourcomponents_stories_mm mmc
ON (cstories.uid = mmc.uid_foreign)
JOIN individualtourscomponents components
ON (components.uid = mmc.uid_local)
JOIN individualtourcomponents_countries_rel componentcountryrel
ON (components.uid = componentcountryrel.componentid)
JOIN countries ccountries
ON (ccountries.uid = componentcountryrel.countryid)
WHERE ccountries.uid = ?
AND components.deleted = 0
AND components.hidden = 0
AND cstories.deleted = 0
AND cstories.hidden = 0
)

MySQL join only selected rows

SELECT invoices.number_formatted, SUM(invoices_elements.netto)
FROM invoices
LEFT JOIN invoices_elements ON invoices_elements_code_invoices_id = invoices_id
WHERE invoices_enable = 1
AND invoices_elements_enable = 1
GROUP BY invoices_elements_code_invoices_id
If table "invoices_elements" doesn't have any rows with "invoices_elements_enable = 1" this query return NULL - but i want "number formatted". So i do this:
SELECT SUM(netto)
FROM (invoices)
LEFT JOIN (SELECT * FROM invoices_elements WHERE invoices_elements_enable = 1) ON invoices_elements_code_invoices_id = invoices_id
WHERE invoices_enable = 1
GROUP BY invoices_elements_code_invoices_id
... and this of coz works. But - is better way to do it?
You can do
SELECT SUM(netto)
FROM invoices
LEFT JOIN invoices_elements
ON invoices_elements_code_invoices_id = invoices_id
AND invoices_elements_enable = 1
WHERE invoices_enable = 1
GROUP BY invoices_elements_code_invoices_id
Note the restriction invoices_elements_enable = 1 is in the ON clause to avoid converting the query into an inner join.