SQL左联接同一个表,但条件可能?

SQL左联接同一个表,但条件可能?,sql,sql-server,join,conditional-statements,Sql,Sql Server,Join,Conditional Statements,我有一张主桌 |-------------|------------| | Procedure | Modifier | |:------------|:-----------| | AA | 00 | | AA | 21 | | AA | 26 | |-------------|------------| 还有一张价目表 |-------------|------------|---

我有一张主桌

|-------------|------------|
| Procedure   | Modifier   |
|:------------|:-----------|
|     AA      |     00     |
|     AA      |     21     |
|     AA      |     26     |
|-------------|------------|
还有一张价目表

|-------------|------------|-------|
| Procedure   | Modifier   | Rate  |
|:------------|:-----------|-------|
|     AA      |     00     | $10   |
|     AA      |     21     | $20   |
|     AA      |     QA     | $30   |
|-------------|------------|-------|
我希望将速率表左键连接到程序和修改器的主表,以找到速率

但是,如果没有匹配的过程和修饰符,那么我想通过过程和修饰符00连接,以获得$10的费率

最终结果是这样的,, |

不是


我认为“更糟”的情况是分开做,并分成两个陈述。我的第一个左连接是通过proc和修饰符,然后在我的第二个语句中通过procedure?有没有一种方法可以在一条语句中执行此操作?

架构和插入语句:

 create table maintable ([Procedure]   varchar(10), Modifier   varchar(10));
 insert into maintable values(     'AA'  ,        '00');     
 insert into maintable values(     'AA' ,         '21');
 insert into maintable values(     'AA',          '26'); 
 
 create table  rates ( [Procedure]   varchar(10), Modifier   varchar(10), Rate  varchar(10));
 insert into rates values(     'AA'        ,   '00',      '$10');
 insert into rates values(     'AA'       ,    '21' ,     '$20');
 insert into rates values(     'AA'      ,     'QA'  ,    '$30');
带有子查询的查询1:

     select m.[Procedure]   , m.Modifier ,(case when r.rate is null then (select rate from rates where rates.[procedure]=m.[procedure] and rates.modifier='00') else r.rate  end)rate
     from maintable m
     left join rates r on m.[Procedure]  =r.[Procedure]   and    m.Modifier  =r.Modifier  
     
输出:

程序 修饰语 速度 AA 00 $10 AA 21 $20 AA 26 $10
您可以使用CASE语句。下面的示例从主表匹配过程和修改器上的rate表执行左连接。case语句将null值替换为10,或者使用rate(如果存在)

select 
    m.procedure,
    m.modifier,
    case when r.rate is null then 10 else r.rate end as rate
from main_table m
left join rates_table r on (m.procedure = r.procedure and m.modifier = r.modifier)

这方面的一个变体是在select子句中使用apply运算符而不是相关子查询,也可以使用coalesce来代替大小写表达式,如果左连接或外部apply没有匹配率,则可以使用10:

select 
     m.[procedure]
   , m.modifier
   , coalesce(r.rate, oa.rate, 10) as rate
from maintable m
left join rates r on m.[procedure] = r.[procedure] and m.modifier = r.modifier
outer apply (
    select rate 
    from rates 
    where rates.[procedure]=m.[procedure] and rates.modifier='00'
    ) oa
通过两个左连接,您可以轻松完成这项工作

注意,这与Kazi的答案非常相似,只是语法更简单

选择 m、 [程序], m、 修饰语, isnullr.rate,r2.rate 来自主表m m.[Procedure]=r.[Procedure]和m.Modifier=r.Modifier上的左联接速率r m.[Procedure]=r2.[Procedure]上的左联接速率r2 和r2。修饰符='00' r.rate为空
请让我们看看你的尝试。下次我会尝试的!我真的很感谢每个人的意见,我想约翰已经立即编辑了我的帖子,因为我的桌子现在看起来不像样子了。对这一切都是陌生的,我会的!很抱歉,我没有指定下一组过程可能不是10。但如果默认值始终为10,那么这是一个简洁快速的解决方案。谢谢你们两位。我想你们是说一个案例表达吧?因为SQL Server没有case语句:谢谢Kazi!我喜欢这个解决方案,因为我是sql的新手,我想我已经把注意力集中在我加入的“条件”上了,所以我的解决方案“必须”包括一个案例陈述或其他东西。。非常感谢。非常抱歉让您知道我以前的解决方案不起作用。我已经改变了我的答案。@DaleK在你的建议之后,我总是试图删除>,但有时时间不够。然后我试着稍后编辑我的答案。我只能测试这个解决方案,它可以工作!虽然我不完全了解外部应用,但在使用前我会先查找并更好地理解,谢谢您介绍这个简洁的替代方案@申。这是最好的解决方案。我刚刚测试运行了它,它工作了,我同意它更容易阅读。注意,我必须将Charie在r.Modifier='00'上的语法更改为'r2.Modifier='00'。感谢查理和戈登的支持!聪明的一个@Charlieface。但这不是更慢吗?只是好奇而已。@KaziMohammadAliNur 99%确信这将与您的第一个查询一样优化,它甚至可能更好,因为您的查询最终可能会强制嵌套循环联接。您的第二个查询也可以重写为具有相同效果的左连接,唯一的区别是它没有基于第一个查询的纾困条件join@Charlieface毫无疑问,我会接受你的答案,我非常喜欢。我甚至投了更高的票。但当我在sql server中对OP提供的数据进行测试时,使用子查询的解决方案需要40%的时间,而使用该解决方案需要60%的时间。这就是我问的原因。这会随着行数的增加而改变吗?我也这么认为。这就是为什么这次友好的讨论。只是为了了解更多。
select 
    m.procedure,
    m.modifier,
    case when r.rate is null then 10 else r.rate end as rate
from main_table m
left join rates_table r on (m.procedure = r.procedure and m.modifier = r.modifier)
select 
     m.[procedure]
   , m.modifier
   , coalesce(r.rate, oa.rate, 10) as rate
from maintable m
left join rates r on m.[procedure] = r.[procedure] and m.modifier = r.modifier
outer apply (
    select rate 
    from rates 
    where rates.[procedure]=m.[procedure] and rates.modifier='00'
    ) oa