左连接列不在两个表之间的关系中

ins*_*ode 6 sql database postgresql left-join

我有2张桌子:

CREATE TABLE plans
    (id int, benefit varchar(5), clip_state int);

INSERT INTO plans
    (id, benefit, clip_state)
VALUES
    (1, 'A', 1),
    (2, 'A', 0),
    (3, 'B', 0),
    (4, 'C', 0);

CREATE TABLE clip_states
    (state varchar(2), clip_state int);

INSERT INTO clip_states
    (state, clip_state)
VALUES
    ('LA', 1),
    ('FL', 0);
Run Code Online (Sandbox Code Playgroud)

请注意,它clip_state是0或1,数据模型允许从2个信息中查询表中的一个或没有计划plans:benefit&state.首先,使用benefit条件下,我们可以在过滤plans表至多为2行,一个具有clip_state通过使用= 0,和一个= 1.然后state,用联接clip_states表,我们可以通过检查结果减小到一排(或零):

  • 如果stateclip_states表中,请确保clip_state在两个表之间匹配.如果不匹配,则不返回任何结果.
  • 如果state不存在clip_states,则它仅与plans表中具有clip_state= 0 的行匹配.

这是我的查询,可以解决这个问题:

SELECT id, p.clip_state, benefit
FROM plans p
LEFT JOIN clip_states cs ON STATE IN ('LA')
WHERE benefit = 'A' AND
(p.clip_state = cs.clip_state OR (p.clip_state = 0 AND cs.clip_state IS NULL));
Run Code Online (Sandbox Code Playgroud)

如您所见,左连接非常奇怪,因为它不会连接2个表之间的关系.所以,我的问题是:

  • 有这种联系是正常的吗?
  • 有没有更好的解决方案(清洁和性能)?

您可以访问http://sqlfiddle.com/#!1/8912d/53查看我的解决方案

更新1:我已更新上述问题的文本.

更新2:更多信息

  1. 如果a state不在clip_states表中,则其clip_state隐式等于0.否则,它clip_state在表中.
  2. 从两个给定的信息:benefitstate,在plans表中找到一行plans.clip_state= clip_state给出的那个state.当然,如果它不匹配,则不返回任何行.

ins*_*ode 0

我想我必须使用以下查询作为解决方案。我已经检查了查询计划,发现它比我在问题中的查询好一步。这个想法是首先缩小计划范围,然后与clip_states表连接。

SELECT *
FROM (
    SELECT DISTINCT id, clip_state, benefit
    FROM plans
    WHERE benefit = 'A') p
LEFT JOIN clip_states cs ON state IN ('LA')
WHERE (p.clip_state = cs.clip_state OR (p.clip_state = 0 AND cs.clip_state IS NULL));
Run Code Online (Sandbox Code Playgroud)

谢谢大家。