确定SELECT是等效的

时间:2012-10-03 12:57:57

标签: sql sql-server-2008 tsql

你能帮我确定这两个SELECT是否相同吗?

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

2 个答案:

答案 0 :(得分:3)

不,他们不是。第二个为每个匹配产生多行,因为添加了JOIN。您试图通过添加DISTINCT来撤消此操作,但这不同。 如果 SessionData.SESSION_DATA_ID是唯一键,则结果可能匹配,但不是相同的查询,因为结果匹配的事实第一个查询是由实际值(唯一性)产生的副作用,而不是请求(查询)的固有属性。 QED。

答案 1 :(得分:3)

这使它与众不同

OR sr.EVENT_NAME为NULL

首先在sr.EVENT_NAME上不匹配为NULL 第二个匹配sr.EVENT_NAME为NULL

第二种情况会在两种情况下相匹配 - sd.SESSION_DATA_ID = sr.SESSION_DATA_ID无匹配 - 匹配sd.SESSION_DATA_ID = sr.SESSION_DATA_ID和sr.EVENT_NAME为NULL

我怀疑第一个选择没有做你认为它正在做的事情 WHERE中的OR IS NULL将返回连接不匹配的行 以下不等效

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)

我怀疑这是你的意思/想要的是:

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在OR之前处理

Operator Precedence (Transact-SQL)

  select 'yes' 
  where 1 = 0 and 0 = 1 or 1 = 1