I have 2 tables:
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);
Please noted that the clip_state is either 0 or 1 and the data model allows to query for one or no plan in plans table from 2 information: benefit & state. First, using benefit condition, we can filter the plans table to 2 rows at most, one with clip_state = 0, and one = 1. Then by using state and join with the clip_states table, we can reduce the result to one row (or zero) by checking:
- If the
stateis inclip_statestable, make sure theclip_stateis matched between 2 tables. If no match, no result returned. - If the
statedoesn’t exist inclip_states, it only matches with the row inplanstable that hasclip_state= 0.
Here is my query that does the trick:
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));
As you can see, the left join is quite strange because it doesn’t join on the relationship between the 2 tables. So, my question is:
- Is it normal to have such kind of join?
- Is there any better solution (clean & performance)?
You can check my solution at: http://sqlfiddle.com/#!1/8912d/53
Updated 1: I have updated the text of the question above.
Updated 2: More information
- If a
stateisn’t inclip_statestable, itsclip_stateimplicitly equals to 0. Otherwise, itsclip_stateis in the table. - From the two given info:
benefitandstate, find a row inplanstable whereplans.clip_state=clip_stateof that givenstate. Of course if it doesn’t match, no row returned.
I guess I have to use the following query as the solution. I have checked the query plan and see it one step better than my query in the question. The idea is to narrow down plan first, then join with the clip_states table.
Thanks all.