【问题标题】:How would be the right way to use EXISTS clause如何使用 EXISTS 子句的正确方法
【发布时间】:2017-04-17 23:27:27
【问题描述】:

在我的 SP 中,我正在创建一个临时表 #PolicyNumbers,并根据将提供给 SP 的参数用 Policy Numbers 填充它。

CREATE TABLE #PolicyNumbers  (PolicyNumber varchar(50))
INSERT INTO #PolicyNumbers SELECT   PolicyNumber
                            FROM    PlazaInsuranceWPDataSet 
                            WHERE   State IN (SELECT * FROM [dbo].[StringOfStringsToTable](@State,','))  
                            AND Coverage IN (SELECT * FROM [dbo].[StringOfStringsToTable](@Coverage,','))
                            AND SICCode IN (SELECT * FROM [dbo].[StringOfStringsToTable](@SICCode,','))

在我的 SP 下方,我使用EXISTS 语句仅过滤那些 PolicyNumbers 是根据参数选择的。

WHERE   EXISTS (SELECT PolicyNumber FROM #PolicyNumbers pn WHERE pn.PolicyNumber = piwp.PolicyNumber)

所以#PolicyNumbers 的结果确实包含重复的 PolicyNumber:

然后在我的 SP 中,我有 SELECT 语句,结果还包含重复的 PolicyNumbers:

SELECT 
            PolicyNumber,
            Cast(PolicyEffectiveDate AS DATE) AS PolicyEffectiveDate,
            Cast(PolicyExpirationDate AS DATE) AS PolicyExpirationDate,
            WrittenPremium
            FROM PlazaInsuranceWPDataSet

现在我正在使用EXIST 声明:

SELECT 
        PolicyNumber,
        Cast(PolicyEffectiveDate AS DATE) AS PolicyEffectiveDate,
        Cast(PolicyExpirationDate AS DATE) AS PolicyExpirationDate,
        WrittenPremium
        FROM PlazaInsuranceWPDataSet piwp
        WHERE   EXISTS (SELECT PolicyNumber FROM #PolicyNumbers pn WHERE pn.PolicyNumber = piwp.PolicyNumber)

到目前为止一切都正确吗? 如果是,那么为什么我使用SELECT 语句和使用IN (@MyParameter) 在WHERE 子句中传递相同参数的结果略有不同?

SELECT 
            PolicyNumber,
            Cast(PolicyEffectiveDate AS DATE) AS PolicyEffectiveDate,
            Cast(PolicyExpirationDate AS DATE) AS PolicyExpirationDate,
            WrittenPremium
            FROM PlazaInsuranceWPDataSet piwp
            WHERE    State IN (@State) 
                    AND SICCode IN (@SICCode)
                    AND Coverage IN (@Coverage)

【问题讨论】:

    标签: sql-server tsql stored-procedures exists


    【解决方案1】:

    您的两个查询之间的区别在于,第一个查询获取策略编号列表,其中表中至少有一个行与StateSICodeCoverage 匹配。由于PlazaInsuranceWPDataSet 中有多个行,并且每个行可以有不同的StateSICodeCoverage(推测),这与仅从PlazaInsuranceWPDataSet 中选择与这三个谓词匹配的行不同。

    这是一个简化的例子:

    Create Table PlazaInsuranceWPDataSet  (
        PolicyNumber varchar(1),
        State varchar(3))
    
    Insert Into PlazaInsuranceWPDataSet 
    Values  ('A', 'Qld'),
            ('A', 'NSW');
    
    Create Table #PolicyNumbers (PolicyNumber char(1));
    Insert Into #PolicyNumbers
    Select PolicyNumber
      From PlazaInsuranceWPDataSet 
      Where State = 'Qld';
    
    -- Returns all policy numbers where at least one row matches the predicate.
    Select *
      From PlazaInsuranceWPDataSet As piwp
      Where Exists (Select 1 From #PolicyNumbers As pn
                    Where pn.PolicyNumber = piwp.PolicyNumber);
    
    -- Returns only rows of 'A' that match the filter predicate                    
    Select *
      From PlazaInsuranceWPDataSet 
      Where State = 'Qld';
    

    策略编号“A”的行中的一个(并且只有一个)与条件匹配,因此当我们在临时表中写下该策略编号并稍后进行比较时,我们将返回所有“A”行.

    【讨论】:

    • #Mendosi 谢谢。很棒的解释。并感谢您的示例。很高兴知道这一点。它只是让我想到另一个问题,哪种方式是正确的?或者我应该说更合适?还是取决于目标?目标是根据参数选择保单编号,然后计算这些保单的收益。我想使用只有特定 SICCode、State 和 Coverage 的保单。所以我认为使用#PolicyNumbersEXISTS 是正确的方法。我说的对吗?
    • 听起来EXISTS 版本适合您回答这个问题。
    猜你喜欢
    • 1970-01-01
    • 2011-02-03
    • 2011-10-28
    • 2016-11-20
    • 2012-01-19
    • 2015-06-17
    • 2019-06-03
    • 2012-05-16
    • 2021-12-11
    相关资源
    最近更新 更多