【问题标题】:LEFT OUTER JOIN, filtered by date左外连接,按日期过滤
【发布时间】:2013-12-31 14:13:10
【问题描述】:

我想查询这个:
选择以下合同:
- 活跃,
- 现在开始日期之前,
- 现在结束日期为 AFTER,
并且,
- 没有匹配的租金记录。

请注意,Rent.month 是日期数据类型列,内容格式为“yyyy-mm-dd”。
如果这个条件被删除,我得到正确的记录。

使用这个查询我得到一个空的结果集

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

我做错了什么?

编辑

我也试过 AND DATE_FORMAT(Rent.month, '%Y-%m' ) = DATE_FORMAT( NOW( ) , '%Y-%m' ) 同一个空集

【问题讨论】:

  • 你想要这部分 'AND DATE_FORMAT(Rent.month, '%Y-%m') DATE_FORMAT(NOW(), '%Y-%m')'连接谓词不是 where?
  • WHERE 子句中对Rent.month 的测试消除了所有Rent.month 为空的记录,隐式地将您的外部联接变为内部联接。您必须在连接条件内执行该测试(或者将 OR Rent.month IS NULL 添加到 WHERE 子句,使用括号来应用正确的优先级)。

标签: mysql left-join outer-join


【解决方案1】:

此条件过滤所有不为空的租金匹配

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

虽然此条件过滤所有 null 匹配的租金

AND `Rent`.`id` IS NULL

第一个条件似乎不符合您的任何初始要求,基本上是这样的: - 没有匹配的租金记录。

我将尝试从 where 子句中删除第一个条件。

评论后编辑: 我更喜欢编写不匹配条件的一种方法是以这种方式使用存在运算符:

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' )
)

这种方式对我来说更具可读性和可维护性。

【讨论】:

  • 我需要这个标准,所以我把它改成了=而不是&lt;&gt;。再次清空
  • Sorry yossi 可能我没理解“that have NO match record from rents”这句话的意思。也许正确的解决方案是按照 Mike 和 eggyal 的建议在连接谓词中添加标准。但是这句话应该是:
猜你喜欢
  • 2021-12-25
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-17
  • 2011-02-01
相关资源
最近更新 更多