SQL JOIN结果不符:Notetext为何出现在分支'CLE'?
WHERE子句将LEFT JOIN转为INNER JOIN,数据范围异常
你这查询从notetext起点做LEFT JOIN,但WHERE里加了JS.JS_JobNumber = 'S0154'。LEFT JOIN原本允许jobshipment(JS)字段为空,但空值和任何值比对都不成立,这会自动过滤掉所有未匹配到该Job的备注记录,等于把LEFT JOIN jobshipment变相改成了INNER JOIN。如果你的预期包含和该Job无关的备注,这会直接丢失数据;要是仅需查询该Job的备注,从jobshipment作为查询起点逻辑会更合理。最后一次Branch表关联条件错误,导致分支编码匹配混乱
你最后关联Branch表(别名gb)的条件是GB.gb_company = gc.gc_pk AND gbb.gb_pk = gb.gb_pk,这相当于要求:这个Branch既要属于当前关联的公司,又要和之前从jobheader关联到的分支(gbb)主键完全相同。这逻辑明显矛盾——gbb是Job所属部门对应的分支,gb应该是公司总部的分支,两者主键不可能相同。要么数据库存在主键重复、所属公司不同的异常Branch记录,导致错误匹配到了'CLE'分支;要么gb字段全为空,结果里的分支编码只能取gbb的值,刚好就是不符合预期的'CLE'。表关联顺序不合理,易引发空值传递错误
从notetext出发关联所有业务表再过滤JobNumber,容易出现关联链上空值传递,导致后续Branch关联匹配到错误记录。正常逻辑应该从已知JobNumber的jobshipment开始,先关联jobheader、Branch,最后再LEFT JOINnotetext和Company,能减少空值干扰,逻辑更清晰。
修正后的SQL示例
SELECT JS.JS_JobNumber as 'JobNumber', gbb.GB_Code AS 'Branch', gb.GB_Code as 'Company', jh.jh_Dept as 'Dept', ISNULL(ST.ST_NoteText, '') AS 'Note Text' FROM jobshipment js (NOLOCK) INNER JOIN jobheader jh (NOLOCK) ON jh.jh_parentID = js.js_pk INNER JOIN Branch gbb (NOLOCK) ON jh.jh_ge = gbb.GB_PK LEFT JOIN Company gc (NOLOCK) ON jh.jh_company = gc.gc_pk -- 假设jobheader有直接关联公司的字段 LEFT JOIN Branch gb (NOLOCK) ON gb.gb_company = gc.gc_pk -- 关联公司对应的分支,无需与gbb主键相等 LEFT JOIN notetext st (NOLOCK) ON st.ST_ParentID = js.JS_PK AND st.st_gc_relatedCompany = gc.gc_pk WHERE JS.JS_JobNumber = 'S0154'
内容的提问来源于stack exchange,提问作者Nick

