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