Question

I want to query this:
select the contracts that are:
- active,
- with start_date BEFORE now,
- with end_date AFTER now,
AND,
- that have NO matched record from rents.

Note that Rent.month is a date data-type column, with "yyyy-mm-dd" content format.
If this condition is removed, i get the correct records.

Using this query i get an empty result-set

SELECT `Contract`.*
FROM `contracts` AS `Contract`
LEFT JOIN `rents` AS `Rent` ON ( `Rent`.`contract_id` = `Contract`.`id` )
WHERE 
Contract`.`active` = 1
AND `Contract`.`end_date` > NOW( )
AND `Contract`.`start_date` < NOW( )
AND DATE_FORMAT( `Rent`.`month` , '%Y-%m' ) <> DATE_FORMAT( NOW( ) , '%Y-%m' )
AND `Rent`.`id` IS NULL

What am i doing wrong?

edit

I also tried AND DATE_FORMAT(Rent.month, '%Y-%m' ) = DATE_FORMAT( NOW( ) , '%Y-%m' ) same empty set

Was it helpful?

Solution

This condition filters all not null match of rent

AND DATE_FORMAT( `Rent`.`month` , '%Y-%m' ) <> DATE_FORMAT( NOW( ) , '%Y-%m' )

While this condition filters all null match of rent

AND `Rent`.`id` IS NULL

The first condition doesn't seem to meet any of your initial requirements and basically this: - that have NO matched record from rents.

I will try to remove first condition from where clause.

edited after comment: A way that I prefer to write condition of no match is using the exists operator in this manner:

SELECT `Contract`.*
FROM `contracts` AS `Contract`
WHERE 
Contract`.`active` = 1
AND `Contract`.`end_date` > NOW( )
AND `Contract`.`start_date` < NOW( )
AND NOT EXISTS (
  SELECT * FROM `rents` AS `Rent` 
  WHERE
  `Rent`.`contract_id` = `Contract`.`id` 
  AND DATE_FORMAT( `Rent`.`month` , '%Y-%m' ) <> DATE_FORMAT( NOW( ) , '%Y-%m' )
)

This way is more readable and maintainable to me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top