Sql 如何仅在某些列不为空的行上联接?

Sql 如何仅在某些列不为空的行上联接?,sql,sql-server,Sql,Sql Server,完成这项任务最有效的方法是什么。我知道有很多方法可以让它做我想做的事情,或者在where子句中做一些事情,或者做一个子查询,但是我不知道哪种方法是最好的 我有一个简单的问题,我真正的问题要复杂得多,所以这很重要,但问题只涉及这一部分: select s.Item_Number ,sr.Royalty_Code ,rc.Royalty_Percentage ,rc.From_Date ,rc.To_Date --,* from Style S LEFT JOIN [JMNYC-AMTDB

完成这项任务最有效的方法是什么。我知道有很多方法可以让它做我想做的事情,或者在where子句中做一些事情,或者做一个子查询,但是我不知道哪种方法是最好的

我有一个简单的问题,我真正的问题要复杂得多,所以这很重要,但问题只涉及这一部分:

select s.Item_Number
,sr.Royalty_Code
,rc.Royalty_Percentage
,rc.From_Date
,rc.To_Date
--,* 
from Style S 

LEFT JOIN   [JMNYC-AMTDB].[AMTPLUS].[dbo].Style_Royalty SR WITH (NOLOCK)        
                                    on S.Company_Code = SR.Company_Code
                                    and S.Division_Code = SR.Division_Code
                                    and S.Item_Number = SR.Item_Number
                                    and S.Color_Code = SR.Color_Code

LEFT JOIN   [JMNYC-AMTDB].[AMTPLUS].[dbo].Royalty_By_Customer RC WITH (NOLOCK)  
                                    on S.Company_Code = RC.Company_Code
                                    and S.Division_Code = RC.Division_Code
                                    and SR.Royalty_Code = RC.Royalty_Code
                                    and RC.Customer_Number ='ecom2x'

where S.Item_Number = '910B1976NSZ' 
这就是结果

+-----------------+--------------+--------------------+-------------------------+-------------------------+
|   Item_Number   | Royalty_Code | Royalty_Percentage |        From_Date        |         To_Date         |
+-----------------+--------------+--------------------+-------------------------+-------------------------+
| 910B1976NSZ     | LOONEY       | 10.00              | NULL                    | NULL                    |
| 910B1976NSZ     | LOONEY       | 14.00              | 2016-10-01 00:00:00.000 | 2099-12-31 00:00:00.000 |
+-----------------+--------------+--------------------+-------------------------+-------------------------+
让它忽略起始日期和截止日期为空的行的最有效方法是什么?我只是在连接后的RC.From_Date不为null的地方进行操作,还是为所有非null行选择,然后只剩下连接?或者,有没有一种方法可以不使用子查询而直接在联接中执行此操作

这是解决问题的有效方法吗

LEFT JOIN   [JMNYC-AMTDB].[AMTPLUS].[dbo].Royalty_By_Customer RC WITH (NOLOCK)  
                                        on S.Company_Code = RC.Company_Code
                                        and S.Division_Code = RC.Division_Code
                                        and SR.Royalty_Code = RC.Royalty_Code
                                        and O.Customer_Number = RC.Customer_Number
                                        and RC.From_Date < O.Date_Entered
                                        and RC.To_Date > O.Date_Entered

我想到两个选择:

where rc.from_date is not null and rc_to_date is not null
但是,空值可能是由左连接创建的。我建议将其替换为内部连接


如果原始表中有空值,则将左连接更改为内部连接,并添加WHERE子句。

您可以在JOIN语句中添加筛选器,这将缩小第二个表的结果范围

LEFT JOIN   [JMNYC-AMTDB].[AMTPLUS].[dbo].Royalty_By_Customer RC WITH (NOLOCK)  
                                    on S.Company_Code = RC.Company_Code
                                    and S.Division_Code = RC.Division_Code
                                    and SR.Royalty_Code = RC.Royalty_Code
                                    and RC.Customer_Number ='ecom2x'
                                    and RC.From_Date is not null
                                    and RC.To_Date is not null

否,空值在原始RC表中。因此,最好是在where子句中执行,然后直接在join中执行?我已经看到,通过将筛选器从内部联接条件移动到where子句,性能有了显著提高,即使查询计划更频繁地完全相同。有时候,一个应用程序会添加一个冗余过滤器,只是为了看看它是否会更改查询计划。@nathan:是的,您将执行更少的连接。是的,我现在刚刚想到了这一点。你知道这比在where子句中做更好还是更糟吗?或者,从逻辑上讲,在联接中这样做更有意义,因为两个表之间要联接的记录更少。然而,SQLServer做了SQLServer希望大多数数据库做的事情。两种方法都试一下,用哪一种效果更好。您可能会发现,随着更多数据添加到表中,结果可能会发生变化。但是,如果要对各个字段进行筛选,请确保具有正确的索引。我认为实际执行计划给出了一些提示,说明哪些索引将有助于提高性能。