需要左表的所有记录,但如果在右表上有匹配,我有进一步的限制

时间:2013-11-08 06:39:36

标签: sql

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

我需要左表的所有记录,而不管右边的匹配。如果在右表上匹配,则可能会有多个匹配,并且我运行子查询以获得正确的匹配。

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

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

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

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满足在键上匹配的所有可用日期中的条件这些日期是最新的日期,仍属于各自的期间_x。

伪代码是“如果匹配key1 = key2”,则对于所有此类匹配,返回具有最新日期的那个匹配在billing_period中。如果根本没有匹配,只需返回左表记录'。

2 个答案:

答案 0 :(得分:2)

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

A LEFT JOIN B
WHERE B.SomeColumn IS NULL OR (some condition)

答案 1 :(得分: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。似乎工作得很好。

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