3

我发现非常相似的问题都涉及 WHERE 子句中的限制问题,从而破坏了 LEFT JOIN 的预期效果。但我无法将这些问题和答案扩展到我的情况。

无论右侧匹配如何,我都需要左表的所有记录。如果在正确的表上有一个匹配,可能会有多个匹配,我运行一个子查询来获得正确的一个。

左表的每一行都有一个键和一个计费周期名称,右表具有相同的键和日期交易。如果键上有匹配项,那么我需要只返回右表中的记录,该记录的交易日期是匹配左表记录中相应计费周期的最新交易日期。

所以,因为从右表中选择正确匹配记录的 WHERE 语句是一个子查询,所以我不能将它粘贴在我的 LEFT JOIN 的 ON 部分。

我的下一个方法是继续让事情作为内部查询运行,然后将这些结果与第二个查询联合起来以获取不匹配的左表记录。这听起来很糟糕,但我对蛮力方法并不陌生。

key1 billing_period                   key2      date     value
 1    period_1                         1        date_1     a1
 2    period_1                         1        date_2     a2
 3    period_1                         1        date_3     a3
 4    period_1                         3        date_1     a4
                                       3        date_4     a6

所需的输出是

 1   period_1  date_2  a2
 2   period_1
 3   period_1  date_4  a6
 4   period_1

因为 a) 我想要左表中的所有记录,并且 b) date_2 是在键值为 1 的那些中选择的正确日期,并且 date_4 在所有可用日期中符合条件,键值为 3 . 这些日期是仍在相应 period_x 内的最新日期。

伪代码是'如果有一个匹配key1 = key2,那么对于所有这样的匹配返回一个具有在billing_period内的最新日期的匹配。如果根本没有匹配,只需返回左表记录'。

4

2 回答 2

2

基本上你需要一个带有条件的左连接:

A LEFT JOIN B
WHERE B.SomeColumn IS NULL OR (some condition)
于 2013-11-08T06:45:40.537 回答
0

我无法为联接本身设置条件,事实上,解决方案的关键是确保根本没有条件——以便让 LEFT JOIN 完成这项工作。因此,这里的关键是在尝试连接之前确保正确的表是正确的表。

对于这个问题,我首先做了(伪)查询

SELECT key, value, bp.period as period
FROM rtable, bp
WHERE rtable.date = (SELECT max(rtable2.date) from rtable2, bp2
    WHERE rtable2.date BETWEEN bp2.start AND bp2.end
    AND bp2.period = bp.period)

然后在这个 AS [别名] ON 键和句点上做了我的 LEFT JOIN。似乎工作得很好。

在我的问题陈述中,我将右表中的日期值作为输出包含在内,而实际上我实际上并不需要查看这些日期。我的问题定义不佳。下次我会花更多的时间来介绍这个例子。

于 2013-11-15T19:20:48.577 回答