问题
In my SP I am creating a temp table #PolicyNumbers
and populating it with Policy Numbers
based on the parameters that will be supplied to the SP.
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,','))
Further below in my SP I'm using EXISTS
statement to filter only those
PolicyNumber
s that been selected based on parameters.
WHERE EXISTS (SELECT PolicyNumber FROM #PolicyNumbers pn WHERE pn.PolicyNumber = piwp.PolicyNumber)
So the result from #PolicyNumbers
DOES contain duplicates PolicyNumbers:
Then furthure in my SP I have SELECT
statement and the result also contains duplicate PolicyNumber
s:
SELECT
PolicyNumber,
Cast(PolicyEffectiveDate AS DATE) AS PolicyEffectiveDate,
Cast(PolicyExpirationDate AS DATE) AS PolicyExpirationDate,
WrittenPremium
FROM PlazaInsuranceWPDataSet
And now I am using EXIST
statement:
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)
Is everything correct so far?
If yes, then why do I have slightly different result using SELECT
statement and passing same parameters in WHERE
clause using IN (@MyParameter)?
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)
回答1:
The difference between your two queries, is that the first gets a list of policy numbers where at least one of the rows in the table matches on State
, SICode
and Coverage
. Since there are multiple rows in PlazaInsuranceWPDataSet
and each can have different State
, SICode
and Coverage
(presumably), this is not the same as selecting only rows from PlazaInsuranceWPDataSet
that match on those three predicates.
Here is a simplified example:
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';
One (and only one) of the rows of policy number 'A' matches the condition so when we write down that policy number in our temp table and then compare to it later we'll get all rows of 'A' back.
来源:https://stackoverflow.com/questions/40942596/how-would-be-the-right-way-to-use-exists-clause