Лучший способ справиться с приведенным ниже условием фильтрации запросов Sql - PullRequest
0 голосов
/ 23 февраля 2012

Рассмотрим приведенный ниже 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 ]

1 голос
/ 23 февраля 2012

Можете ли вы сделать что-то подобное?Не нужно оставлять соединение (сканирование другой таблицы).предположим, что partner_id, квартал, год, 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)
0 голосов
/ 23 февраля 2012

Так что, если я правильно понимаю, вы избегаете вставки данных, которые могут иметь дубликаты, я изменил ваш 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

То, что я пытаюсь сделать здесь, это сначала ВСТАВИТЬ В таблицу и попытаться получить любые данные, если они существуют, а затем с помощью проверки IS NULL отфильтровать любые существующие данные, так что нам не нужно NOT IN, который не работает хорошо и не рекомендуется.

0 голосов
/ 23 февраля 2012

Выполнять соединения, а не внутренние выборки.Это очень грязный SQL.Думайте в наборах, а не процедурах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...