Reputation: 26331
Can you please help me to determine if these 2 SELECTs are equivalent?
SELECT sd.SESSION_DATA_ID
FROM SessionData sd
WHERE sd.DEVICE_TYPE = 'TRAC'
AND (EXISTS
(SELECT sr.ID
FROM SessionResult sr
LEFT JOIN BarcodeValues bv ON
sr.BARCODE_VALUE_0 = bv.ID AND
sr.SESSION_DATA_ID = sd.SESSION_DATA_ID AND
sr.EVENT_NAME = 'Multi Full Cntr'
WHERE
bv.ENCRYPTED_VALUE LIKE '' OR bv.ENCRYPTED_VALUE IS NULL))
SELECT
DISTINCT sd.SESSION_DATA_ID
FROM SessionData sd
LEFT JOIN SessionResult sr ON sd.SESSION_DATA_ID = sr.SESSION_DATA_ID
LEFT JOIN BarcodeValues bv ON bv.ID = sr.BARCODE_VALUE_0
WHERE
sd.DEVICE_TYPE = 'TRAC' AND
(sr.EVENT_NAME = 'Multi Full Cntr' AND
bv.ENCRYPTED_VALUE LIKE '' OR bv.ENCRYPTED_VALUE IS NULL) OR
sr.EVENT_NAME is NULL
Upvotes: 0
Views: 70
Reputation: 45096
This makes it different
OR sr.EVENT_NAME is NULL
First will not match on sr.EVENT_NAME is NULL
Second will match on sr.EVENT_NAME is NULL
The second will match in two situations
- no match on sd.SESSION_DATA_ID = sr.SESSION_DATA_ID
- match on sd.SESSION_DATA_ID = sr.SESSION_DATA_ID and sr.EVENT_NAME is NULL
I suspect the first select is not doing what you think it is doing
The OR IS NULL in the WHERE will return rows where the join does not match
The following are NOT equivalent
SELECT sr.ID
FROM SessionResult sr
LEFT JOIN BarcodeValues bv
ON sr.BARCODE_VALUE_0 = bv.ID
AND sr.SESSION_DATA_ID = sd.SESSION_DATA_ID
AND sr.EVENT_NAME = 'Multi Full Cntr'
WHERE bv.ENCRYPTED_VALUE LIKE '' OR bv.ENCRYPTED_VALUE IS NULL
SELECT sr.ID
FROM SessionResult sr
JOIN BarcodeValues bv
ON sr.BARCODE_VALUE_0 = bv.ID
AND sr.SESSION_DATA_ID = sd.SESSION_DATA_ID
AND sr.EVENT_NAME = 'Multi Full Cntr'
AND (bv.ENCRYPTED_VALUE LIKE '' OR bv.ENCRYPTED_VALUE IS NULL)
I suspect this is what you mean / want is:
SELECT distinct sd.SESSION_DATA_ID
FROM SessionData sd
JOIN SessionResult sr
ON sd.SESSION_DATA_ID = sr.SESSION_DATA_ID
AND(sr.EVENT_NAME = 'Multi Full Cntr' or sr.EVENT_NAME is NULL)
JOIN BarcodeValues bv
ON bv.ID = sr.BARCODE_VALUE_0
AND(bv.ENCRYPTED_VALUE = '' OR bv.ENCRYPTED_VALUE IS NULL)
WHERE sd.DEVICE_TYPE = 'TRAC'
AND is processed before OR
Operator Precedence (Transact-SQL)
select 'yes'
where 1 = 0 and 0 = 1 or 1 = 1
Upvotes: 3
Reputation: 294407
No, they're not. The second one produces multiple rows for every match, because of added JOIN. You are trying to undo this by adding a DISTINCT, but that is not the same. If the SessionData.SESSION_DATA_ID is an unique key, then the results may match, but is not the same query because the fact that the results match with the first query is a side effect resulted from the actual values (uniqueness) not an inherent property of the request (query). QED.
Upvotes: 3