我有2张桌子,
Table1 Table2
+----------+--------+----------+ +--------+---------+-------+
| Customer | Part # | Modifier | | Part # | Modifer | Value |
+----------+--------+----------+ +--------+---------+-------+
| Fred | 1 | XYZ | | 1 | Null | 1.5 |
| Fred | 2 | ABC | | 1 | GHI | 2.0 |
| Fred | 2 | DEF | | 2 | Null | 3.0 |
| Fred | 2 | GHI | | 2 | ABC | 3.1 |
| Fred | 3 | ABC | | 2 | DEF | 3.2 |
| Fred | 3 | XYZ | | 3 | Null | 8.0 |
| Fred | 4 | ABC | | 4 | Null | 10.0 |
| Lucy | 1 | GHI | | 5 | Null | 4.0 |
| Lucy | 5 | DEF | | 5 | ABC | 4.5 |
| Lucy | 4 | Null | | 5 | DEF | 4.7 |
+----------+--------+----------+ +--------+---------+-------+
保证ABC,DEF和GHI是表2中唯一的修饰符,因此出于表2的目的可以忽略XYZ。我希望创建一个将Table1连接到Table2的查询,每个客户/部件号只有1个结果,因此连接的结果将是:
+----------+--------+-------+
| Customer | Part # | Value |
+----------+--------+-------+
| Fred | 1 | 1.5 |
| Fred | 2 | 3.0 |
| Fred | 3 | 8.0 |
| Fred | 4 | 10.0 |
| Lucy | 1 | 2.0 |
| Lucy | 5 | 4.7 |
| Lucy | 4 | 10.0 |
+----------+--------+-------+
规则是每个客户每个零件编号只能使用1个修饰符(ABC,DEF,GHI)。因此,Fred,第2部分是错误情况,应返回Null修饰符或3.0的值。如果使用的修饰符不是3个中的1个,则将其视为没有修饰符(或Null)。基本上,除非有单个相关的修饰符(ABC,DEF,GHI)并且为零件#定义了该修饰符,否则应始终返回Null修饰符的值。
我不应该去哪个方向。在不同条件下多次加入Table2吗?使用OVER / PARTITION BY以某种方式对结果进行排名并选择排名靠前的结果?我尝试了几种不同的解决方案,但始终似乎忽略了其中一种条件。
预先感谢您的帮助!
答案 0 :(得分:1)
您可以使用以下方法设置默认值:
select t1.*, coalesce(t2.value, t2null.value) as value
from table1 t1 left join
table2 t2
on t1.part = t2.part and
t1.modifier = t2.modifier left join
table2 t2null
on t1.part = t2null.part and
t2null.modifier is null;
然后每个客户/零件获得一个:
select t.*
from (select t1.*, coalesce(t2.value, t2null.value) as value,
row_number() over (partition by t1.customer, t1.part
order by (case when t2.value is not null then 1 else 2 end)
) as seqnum
from (select t1.*,
sum(case when part in ('ABC', 'DEF', 'GHI') then 1 else 0 end) over (partition by customer) as cnt
from table1 t1
) t1 left join
table2 t2
on t1.part = t2.part and
t1.modifier = t2.modifier and
t1.cnt = 1 left join
table2 t2null
on t1.part = t2null.part and
t2null.modifier is null
) t
where seqnum = 1;