MySQL LEFT JOIN ignores AND criteria - mysql

I have a functional LEFT JOIN MySQL query structured like this:
SELECT
COUNT(HTG_ScheduleRequest.ID) AS current_job,
HTG_TechProps.EmpNumber,
HTG_TechProps.EmpFirstName,
HTG_TechProps.EmpLastName,
HTG_TechProps.Veh_Number
FROM HTG_TechProps
LEFT JOIN HTG_ScheduleRequest ON HTG_TechProps.EmpNumber = HTG_ScheduleRequest.SSR
AND (HTG_ScheduleRequest.ScheduleDateCurrent = CURDATE() || HTG_ScheduleRequest.ScheduleDateExact = CURDATE())
AND RecordType = '1'
AND HTG_ScheduleRequest.JobStatus IN (2,5,8,3,4,7)
GROUP BY HTG_TechProps.EmpNumber ORDER BY HTG_TechProps.EmpNumber ASC
I need to add some criteria to the initial SELECT table like this:
HTG_TechProps.EmpStatus='A'
I get a Syntax error when I add a WHERE statement prior to the LEFT JOIN and when I add an AND like this after the LEFT JOIN it is ignored an still returning records that are not equal to A.
LEFT JOIN HTG_ScheduleRequest ON HTG_TechProps.EmpNumber = HTG_ScheduleRequest.SSR
AND HTG_TechProps.EmpStatus='A'

Conditions on the first table in a LEFT JOIN should go in a WHERE clause:
SELECT COUNT(sr.ID) AS current_job,
tp.EmpNumber, tp.EmpFirstName, tp.EmpLastName, tp.Veh_Number
FROM HTG_TechProps tp LEFT JOIN
HTG_ScheduleRequest sr
ON tp.EmpNumber = sr.SSR AND
(sr.ScheduleDateCurrent = CURDATE() OR sr.ScheduleDateExact = CURDATE()
) AND
sr.RecordType = '1' AND -- assume this comes from SR
sr.JobStatus IN (2, 5, 8, 3, 4, 7)
WHERE tp.EmpStatus='A'
GROUP BY tp.EmpNumber -- this is okay assuming that it is unique or (equivalently) a primary key
ORDER BY tp.EmpNumber ASC;
Note that this introduces table aliases so the query is easier to write and to read.

You should Use OR
SELECT
COUNT(HTG_ScheduleRequest.ID) AS current_job,
HTG_TechProps.EmpNumber,
HTG_TechProps.EmpFirstName,
HTG_TechProps.EmpLastName,
HTG_TechProps.Veh_Number
FROM HTG_TechProps
LEFT JOIN HTG_ScheduleRequest ON HTG_TechProps.EmpNumber = HTG_ScheduleRequest.SSR
AND (HTG_ScheduleRequest.ScheduleDateCurrent = CURDATE() OR HTG_ScheduleRequest.ScheduleDateExact = CURDATE())
AND RecordType = '1'
AND HTG_ScheduleRequest.JobStatus IN (2,5,8,3,4,7)
GROUP BY HTG_TechProps.EmpNumber
ORDER BY HTG_TechProps.EmpNumber ASC
and if you want apply where condtion for main table's columns you could use where eg:
SELECT
COUNT(HTG_ScheduleRequest.ID) AS current_job,
HTG_TechProps.EmpNumber,
HTG_TechProps.EmpFirstName,
HTG_TechProps.EmpLastName,
HTG_TechProps.Veh_Number
FROM HTG_TechProps
LEFT JOIN HTG_ScheduleRequest ON HTG_TechProps.EmpNumber = HTG_ScheduleRequest.SSR
AND HTG_ScheduleRequest.JobStatus IN (2,5,8,3,4,7)
WHERE (HTG_ScheduleRequest.ScheduleDateCurrent = CURDATE() OR HTG_ScheduleRequest.ScheduleDateExact = CURDATE())
AND HTG_TechProps.RecordType = '1'
GROUP BY HTG_TechProps.EmpNumber
ORDER BY HTG_TechProps.EmpNumber ASC

Related

SQL query - two select to one

How can I merge these two selects to one? As a result, I want column "POJ", "locked POJ" and "EV".
SELECT COUNT(VC) AS 'POJ', F.F_C.VC AS 'EV' FROM
F.F_D LEFT JOIN F.F_C ON F.F_D.col_id = F.F_C.id
LEFT JOIN F.F_Z_D ON F.F_D.id = F.F_Z_D.id
where createdTime >= '2021-05-01' and createdTime <= '2022-05-31' and tTemplate = 'ZS' GROUP BY F.F_C.VC;
SELECT COUNT(VC) AS 'locked POJ', F.F_C.VC AS 'EV' FROM
F.F_D LEFT JOIN F.F_C ON F.F_D.col_id = F.F_C.id
LEFT JOIN F.F_Z_D ON F.F_D.id = F.F_Z_D.id
where createdTime >= '2021-05-01' and createdTime <= '2022-05-31' and tTemplate = 'ZS' and locked = 1 GROUP BY F.F_C.VC;
Use conditional aggregation:
SELECT COUNT(VC) AS POJ, SUM(locked = 1) AS `locked POJ`, F.F_C.VC AS EV
FROM F.F_D
LEFT JOIN F.F_C ON F.F_D.col_id = F.F_C.id
LEFT JOIN F.F_Z_D ON F.F_D.id = F.F_Z_D.id
WHERE createdTime BETWEEN '2021-05-01' AND '2022-05-31' AND tTemplate = 'ZS'
GROUP BY F.F_C.VC;
Note that the only difference between the two queries is that the second one has the additional criterion locked = 1 in the WHERE clause. We can remove it and use the first query, along with a conditional count.

group and order in mysql

I have to write a query in which I need the given output.
I tried different queries but didn't work.
Actual data :
and I need Output like :
Queries like :
SELECT VCD.id,VCD.effective_date, `VCD`.`charge_id`, `C`.`head`,
`VCD`.`per`, `VCD`.`currency`, `VCD`.`amount`, `VCD`.`remarks`
FROM `vendor_charge` `VC` INNER JOIN `vendor_charge_details` `VCD`
ON `VC`.`id` = `VCD`.`vc_id` LEFT JOIN `charges` `C`
ON `C`.`id` = `VCD`.`charge_id`
WHERE `VC`.`vendor_id` = '12' AND `VCD`.`effective_date` <= '2018-05-22'
GROUP BY `VCD`.`charge_id`, `VCD`.`per`, `VCD`.`currency`
ORDER BY `C`.`head` DESC
and
SELECT VCD.id,VCD.effective_date, `VCD`.`charge_id`, `C`.`head`,
`VCD`.`per`, `VCD`.`currency`, `VCD`.`amount`, `VCD`.`remarks`
FROM `vendor_charge` `VC` INNER JOIN `vendor_charge_details` `VCD`
ON `VC`.`id` = `VCD`.`vc_id` LEFT JOIN `charges` `C`
ON `C`.`id` = `VCD`.`charge_id`
WHERE `VC`.`vendor_id` = '12' AND `VCD`.`effective_date` <= '2018-05-22'
GROUP BY `VCD`.`charge_id`, `VCD`.`per`, `VCD`.`currency`
ORDER BY `VCD`.`effective_date` DESC
I think all you need here is an additional join to a subquery which finds the latest effective_date for each charge_id:
SELECT
VCD.id,
VCD.effective_date,
VCD.charge_id,
C.head,
VC.per,
VCD.currency,
VCD.amount,
VCD.remarks
FROM vendor_charge VC
INNER JOIN vendor_charge_details VCD
ON VC.id = VCD.vc_id
INNER JOIN
(
SELECT charge_id, MAX(effective_date) AS max_effective_date
FROM vendor_charge_details
GROUP BY charge_id
) t
ON VCD.charge_id = t.charge_id AND VCD.effective_date = t.max_effective_date
LEFT JOIN charges C
ON C.id = VCD.charge_id
WHERE VC.vendor_id = '12' AND VCD.effective_date <= '2018-05-22'
ORDER BY
C.head DESC;

MySQL error: duplicate column

I'm having a bit of a problem with the following MySQL query and I can't find the source of it.
MySQL tells me that
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name
'annonce_dispo_id'
SELECT MAX(max_price) AS `max_price`,
COUNT(*) AS `nb_annonces`,
SUM(nb_dispo) AS `nb_dispo`
FROM
(SELECT `annonce`.`id`,
CEIL(MAX(price)*1.16) AS `max_price`,
COUNT(DISTINCT annonce.id) AS `nb_annonces`,
COUNT(annonce_dispoo.annonce_dispo_id) AS `nb_dispo`,
`annonce_dispo1`.*,
`annonce_dispo2`.*
FROM `annonce`
LEFT JOIN `annonce_dispo` AS `annonce_dispoo` ON (annonce_dispoo.annonceId = annonce.id
AND STR_TO_DATE(annonce_dispoo.dispo_date, '%d/%m/%Y') >= CURDATE())
INNER JOIN `annonce_dispo` AS `annonce_dispo1` ON annonce.id = annonce_dispo1.annonceId
INNER JOIN `annonce_dispo` AS `annonce_dispo2` ON annonce.id = annonce_dispo2.annonceId
WHERE ((annonce.city IN
(SELECT `cities`.`id`
FROM `cities`
WHERE (cities.label LIKE 'lyon%'))
OR annonce.zipcode = 'lyon')
OR (annonce.city LIKE '28674'
OR annonce.zipcode = '28674'))
AND (annonce_dispo1.dispo_date = '27/05/2014')
AND (annonce_dispo1.disponibility = 'available')
AND (annonce_dispo2.dispo_date = '31/05/2014')
AND (annonce_dispo2.disponibility = 'available')
AND (annonce.visible = 1)
AND (annonce.completed = 1)
GROUP BY `annonce`.`id` HAVING (nb_dispo >= 1)) AS `t`
I thought gave a different alias for the table in each JOIN I use them in, and can't really put my finger on what else is possible to output such an error.
Don't select annonce_dispo1.* and annonce_dispo2.* in your subquery, duplicated column names are being returned. Instead select the fields you need and alias accordingly.
SELECT MAX(max_price) AS `max_price`,
COUNT(*) AS `nb_annonces`,
SUM(nb_dispo) AS `nb_dispo`
FROM
(SELECT `annonce`.`id`,
CEIL(MAX(price)*1.16) AS `max_price`,
COUNT(DISTINCT annonce.id) AS `nb_annonces`,
COUNT(annonce_dispoo.annonce_dispo_id) AS `nb_dispo`,
`annonce_dispo1`.field, `annonce_dispo1`.otherfield,
`annonce_dispo1`.field as field2, `annonce_dispo1`.otherfield as otherfield2
FROM `annonce`
LEFT JOIN `annonce_dispo` AS `annonce_dispoo` ON (annonce_dispoo.annonceId = annonce.id
AND STR_TO_DATE(annonce_dispoo.dispo_date, '%d/%m/%Y') >= CURDATE())
INNER JOIN `annonce_dispo` AS `annonce_dispo1` ON annonce.id = annonce_dispo1.annonceId
INNER JOIN `annonce_dispo` AS `annonce_dispo2` ON annonce.id = annonce_dispo2.annonceId
WHERE ((annonce.city IN
(SELECT `cities`.`id`
FROM `cities`
WHERE (cities.label LIKE 'lyon%'))
OR annonce.zipcode = 'lyon')
OR (annonce.city LIKE '28674'
OR annonce.zipcode = '28674'))
AND (annonce_dispo1.dispo_date = '27/05/2014')
AND (annonce_dispo1.disponibility = 'available')
AND (annonce_dispo2.dispo_date = '31/05/2014')
AND (annonce_dispo2.disponibility = 'available')
AND (annonce.visible = 1)
AND (annonce.completed = 1)
GROUP BY `annonce`.`id` HAVING (nb_dispo >= 1)) AS `t`
See here for an example that doesn't work:
http://sqlfiddle.com/#!2/9bb13/1
The problem is that you are selecting all columns in the tables annonce_dispo1 and annonce_dispo2.
The fact that you have attributed different table names doesn't mean that there aren't duplicate column names.
I mean, you should use [Table name].[column name]
Example:
(SELECT `annonce`.`id`,
CEIL(MAX(price)*1.16) AS `max_price`,
COUNT(DISTINCT annonce.id) AS `nb_annonces`,
COUNT(annonce_dispoo.annonce_dispo_id) AS `nb_dispo`,
`annonce_dispo1`.annonce_dispo_id AS `column1`,
`annonce_dispo2`.annonce_dispo_id AS `column2`
I hope I've helped

mysql join with multiple conditions (not OR but AND)

i have problem with join table and use multiple conditions...
My code:
SELECT * FROM
(SELECT sid, MAX(info_date_add) AS max_info_date_add FROM skiresort GROUP BY sid) skiresort_max
INNER JOIN skiresort
ON
skiresort_max.sid = skiresort.sid AND
skiresort_max.max_info_date_add = skiresort.info_date_add
JOIN skiresort_theme_value
ON skiresort_theme_value.skiresort_id = skiresort.id
WHERE
skiresort_theme_value.skiresort_theme_id = '1' AND
skiresort_theme_value.skiresort_theme_id = '2' AND
skiresort_theme_value.skiresort_theme_id = '4'
GROUP BY skiresort.sid
ORDER BY skiresort.title_en
In this code, the conditions are in WHERE clausule. I also tried to put in into JOIN ON (...) but it also didn't work.
When i have only one condition it works. I read some articles about using OR instead of AND, it worked but not as i expected. I need to search only rows with certain IDs (multiple).
why not use this instead of many conditions.
WHERE
skiresort_theme_value.skiresort_theme_id in (1, 2,4)
GROUP BY skiresort.sid
HAVING COUNT(DISTINCT skiresort_theme_value.skiresort_theme_id) = 3
ORDER BY skiresort.title_en
when add condition to WHERE, condition must be from FROM tbl
add condition JOIN ON
Try this:
SELECT * FROM
(SELECT sid, MAX(info_date_add) AS max_info_date_add FROM skiresort GROUP BY sid) skiresort_max
INNER JOIN skiresort
ON
skiresort_max.sid = skiresort.sid AND
skiresort_max.max_info_date_add = skiresort.info_date_add
JOIN skiresort_theme_value
ON (skiresort_theme_value.skiresort_id = skiresort.id AND skiresort_theme_value.skiresort_theme_id = '1' AND skiresort_theme_value.skiresort_theme_id = '2' AND skiresort_theme_value.skiresort_theme_id = '4')
GROUP BY skiresort.sid
ORDER BY skiresort.title_en

MySQL LIMIT in a Correllated Subquery

I have a correlated subquery that will return a list of quantities, but I need the highest quantity, and only the highest. So I tried to introduce an order by and a LIMIT of 1 to achieve this, but MySQL throws an error stating it doesn't yet support limits in subqueries. Any thoughts on how to work around this?
SELECT Product.Name, ProductOption.Name, a.Qty, a.Price, SheetSize.UpgradeCost,
FinishType.Name, FinishOption.Name, FinishTierPrice.Qty, FinishTierPrice.Price
FROM `Product`
JOIN `ProductOption`
ON Product.idProduct = ProductOption.Product_idProduct
JOIN `ProductOptionTier` AS a
ON a.ProductOption_idProductOption = ProductOption.idProductOption
JOIN `PaperSize`
ON PaperSize.idPaperSize = ProductOption.PaperSize_idPaperSize
JOIN `SheetSize`
ON SheetSize.PaperSize_idPaperSize = PaperSize.idPaperSize
JOIN `FinishOption`
ON FinishOption.Product_idProduct = Product.idProduct
JOIN `FinishType`
ON FinishType.idFinishType = FinishOption.Finishtype_idFinishType
JOIN `FinishTierPrice`
ON FinishTierPrice.FinishOption_idFinishOption = FinishOption.idFinishOption
WHERE Product.idProduct = 1
AND FinishTierPrice.idFinishTierPrice IN (SELECT FinishTierPrice.idFinishTierPrice
FROM `FinishTierPrice`
WHERE FinishTierPrice.Qty <= a.Qty
ORDER BY a.Qty DESC
LIMIT 1)
This is a variation of the greatest-n-per-group problem that comes up frequently.
You want the single row form FinishTierPrice (call it p1), matching the FinishOption and with the greatest Qty, but still less than or equal to the Qty of the ProductOptionTier.
One way to do this is to try to match a second row (p2) from FinishTierPrice that would have the same FinishOption and a greater Qty. If no such row exists (use an outer join and test that it's NULL), then the row found by p1 is the greatest.
SELECT Product.Name, ProductOption.Name, a.Qty, a.Price, SheetSize.UpgradeCost,
FinishType.Name, FinishOption.Name, FinishTierPrice.Qty, FinishTierPrice.Price
FROM `Product`
JOIN `ProductOption`
ON Product.idProduct = ProductOption.Product_idProduct
JOIN `ProductOptionTier` AS a
ON a.ProductOption_idProductOption = ProductOption.idProductOption
JOIN `PaperSize`
ON PaperSize.idPaperSize = ProductOption.PaperSize_idPaperSize
JOIN `SheetSize`
ON SheetSize.PaperSize_idPaperSize = PaperSize.idPaperSize
JOIN `FinishOption`
ON FinishOption.Product_idProduct = Product.idProduct
JOIN `FinishType`
ON FinishType.idFinishType = FinishOption.Finishtype_idFinishType
JOIN `FinishTierPrice` AS p1
ON p1.FinishOption_idFinishOption = FinishOption.idFinishOption
AND p1.Qty <= a.Qty
LEFT OUTER JOIN `FinishTierPrice` AS p2
ON p2.FinishOption_idFinishOption = FinishOption.idFinishOption
AND p2.Qty <= a.Qty AND (p2.Qty > p1.Qty OR p2.Qty = p1.Qty
AND p2.idFinishTierPrice > p1.idFinishTierPrice)
WHERE Product.idProduct = 1
AND p2.idFinishTierPrice IS NULL