处理以下Sql查询过滤条件的更好方法

时间:2012-02-23 03:00:55

标签: sql sql-server-2008

考虑以下SQL查询

INSERT INTO [dbo].[PartnerCommissionData] 
SELECT X.*
FROM
(
        SELECT 
                cs.partner_id
                ,cs.quarter 
                ,cs.year
                ,cs.partner_currency_amount
                ,p.partner_email                        
                ,cs.report_status_id    
                ,Creation_dt = GETDATE()    
        FROM [dbo].[CommissionSummary] cs WITH(NOLOCK)
        INNER JOIN [dbo].[Partner] p WITH(NOLOCK) ON p.partner_id = cs.partner_id
        WHERE  
                cs.year = YEAR(@FirstDayOfQuarter)  
        AND     cs.quarter = @Quarter
        AND     cs.report_status_id IN (1,2)
    )X
WHERE 
    X.partner_id NOT IN (SELECT [Partner_Id] FROM [dbo].[PartnerCommissionData] WITH (NOLOCK))
AND X.quarter NOT IN (SELECT [Quarter] FROM [dbo].[PartnerCommissionData] WITH (NOLOCK))
AND X.year NOT IN (SELECT [Year] FROM [dbo].[PartnerCommissionData] WITH (NOLOCK))
AND X.report_status_id NOT IN (SELECT [CommissionStatus_id] FROM [dbo].[PartnerCommissionData] WITH (NOLOCK))

指定的过滤条件表示如果记录已存在于PartnerCommissionData表中,则不应进一步插入。但就我而言,这是一种令人讨厌的实施。

WHERE 
    X.partner_id NOT IN (SELECT [Partner_Id] FROM [dbo].[PartnerCommissionData] WITH (NOLOCK))
AND X.quarter NOT IN (SELECT [Quarter] FROM [dbo].[PartnerCommissionData] WITH (NOLOCK))
AND X.year NOT IN (SELECT [Year] FROM [dbo].[PartnerCommissionData] WITH (NOLOCK))
AND X.report_status_id NOT IN (SELECT [CommissionStatus_id] FROM [dbo].[PartnerCommissionData] WITH (NOLOCK))

我们怎样才能以更好的方式重写它?

我们可以应用合并或任何其他方式....?

提前致谢

3 个答案:

答案 0 :(得分:1)

你能做这样的事吗?不需要离开连接(扫描另一个表)。 假设partner_id,quarter,year,report_status_id需要转换为nvarchar

   INSERT INTO [dbo].[PartnerCommissionData] 
    SELECT X.*
    FROM
    (
            SELECT 
                    cs.partner_id
                    ,cs.quarter 
                    ,cs.year
                    ,cs.partner_currency_amount
                    ,p.partner_email                        
                    ,cs.report_status_id    
                    ,Creation_dt = GETDATE()    
            FROM [dbo].[CommissionSummary] cs WITH(NOLOCK)
            INNER JOIN [dbo].[Partner] p WITH(NOLOCK) ON p.partner_id = cs.partner_id
            WHERE  
                    cs.year = YEAR(@FirstDayOfQuarter)  
            AND     cs.quarter = @Quarter
            AND     cs.report_status_id IN (1,2)
       )X
    WHERE 
    (x.partner_id + x.quarter + x.year + x.report_status_id) <> 
    (partner_id + x.quarter + x.year + x.report_status_id)

答案 1 :(得分:0)

执行连接而不是内部选择。这是非常凌乱的SQL。在集合而不是程序中思考。

答案 2 :(得分:0)

因此,如果我的理解是正确的,那么您要避免插入可能重复的数据,我将SQL更改为以下内容:

    INSERT INTO [dbo].[PartnerCommissionData] 
SELECT X.*
FROM
(
        SELECT 
                cs.partner_id
                ,cs.quarter 
                ,cs.year
                ,cs.partner_currency_amount
                ,p.partner_email                        
                ,cs.report_status_id    
                ,Creation_dt = GETDATE()    
        FROM [dbo].[CommissionSummary] cs WITH(NOLOCK)
        INNER JOIN [dbo].[Partner] p WITH(NOLOCK) ON p.partner_id = cs.partner_id
        WHERE  
                cs.year = YEAR(@FirstDayOfQuarter)  
        AND     cs.quarter = @Quarter
        AND     cs.report_status_id IN (1,2)
    )X
    LEFT JOIN [PartnerCommissionData] PCD WITH (NOLOCK)) 
            ON X.partner_id = PCD.[Partner_Id] OR X.quarter = PCD.[Quarter] 
                OR X.year = PCD.[Year] OR X.report_status_id = PCD.[CommissionStatus_id]
WHERE PCD.ID IS NULL

我在这里尝试做的事情是首先LEFT JOIN表并尝试抓取任何数据(如果存在),然后使用IS NULL检查过滤掉任何现有数据,这样我们就不需要NOT了其中表现不佳且不推荐。