我有一个不是由我创建的存储过程。
在某些存储过程中,存在嵌套连接,我很难理解。
如何更简单地编写它以理解逻辑?还有那些被使用的原因?仅提高绩效?
SELECT *
FROM
dbo.tblQuotes AS tblQuotes_1
LEFT OUTER JOIN
dbo.lstLines ON tblQuotes_1.LineGUID = dbo.lstLines.LineGUID
RIGHT OUTER JOIN
dbo.tblUsers
RIGHT OUTER JOIN
dbo.tblQuotes
RIGHT OUTER JOIN
dbo.tblClaims_Claim ON dbo.tblQuotes.ControlNo = dbo.tblClaims_Claim.ControlNo
RIGHT OUTER JOIN
dbo.tblNoteEntries
LEFT OUTER JOIN
dbo.tblNoteRecipients ON dbo.tblNoteEntries.ID = dbo.tblNoteRecipients.EntryGUID
INNER JOIN
dbo.tblNoteDiaries ON dbo.tblNoteEntries.ID = dbo.tblNoteDiaries.EntryGUID
INNER JOIN
dbo.tblNoteEntities ON dbo.tblNoteEntries.NoteGUID = dbo.tblNoteEntities.NoteGUID
INNER JOIN
dbo.tblNoteStore ON dbo.tblNoteEntries.NoteGUID = dbo.tblNoteStore.ID
AND dbo.tblNoteDiaries.NoteGUID = dbo.tblNoteStore.ID
AND dbo.tblNoteEntities.NoteGUID = dbo.tblNoteStore.ID
INNER JOIN
dbo.lstNoteTypes ON dbo.tblNoteStore.Type = dbo.lstNoteTypes.NoteTypeID
ON dbo.tblClaims_Claim.ClaimGuid = dbo.tblNoteEntities.AssociatedEntityGUID
ON dbo.tblUsers.UserGUID = dbo.tblNoteRecipients.UserGUID
ON tblQuotes_1.ControlGuid = dbo.tblNoteEntities.ControlGuid
LEFT OUTER JOIN
dbo.tblMaxQuoteIDs ON tblQuotes_1.QuoteID = dbo.tblMaxQuoteIDs.MaxQuoteID
LEFT OUTER JOIN
dbo.tblInsureds ON dbo.tblNoteEntities.AssociatedEntityGUID = dbo.tblInsureds.InsuredGUID
答案 0 :(得分:2)
我通常将列表转换为缩进列表,就好像各种连接是嵌套的IF语句一样。例如:
SELECT *
FROM dbo.tblQuotes AS tblQuotes_1
LEFT OUTER JOIN dbo.lstLines
ON tblQuotes_1.LineGUID = dbo.lstLines.LineGUID
RIGHT OUTER JOIN dbo.tblUsers
RIGHT OUTER JOIN dbo.tblQuotes
RIGHT OUTER JOIN dbo.tblClaims_Claim
ON dbo.tblQuotes.ControlNo = dbo.tblClaims_Claim.ControlNo
RIGHT OUTER JOIN dbo.tblNoteEntries
LEFT OUTER JOIN dbo.tblNoteRecipients
ON dbo.tblNoteEntries.ID = dbo.tblNoteRecipients.EntryGUID
INNER JOIN dbo.tblNoteDiaries
ON dbo.tblNoteEntries.ID = dbo.tblNoteDiaries.EntryGUID
INNER JOIN dbo.tblNoteEntities
ON dbo.tblNoteEntries.NoteGUID = dbo.tblNoteEntities.NoteGUID
INNER JOIN dbo.tblNoteStore
ON dbo.tblNoteEntries.NoteGUID = dbo.tblNoteStore.ID
AND dbo.tblNoteDiaries.NoteGUID = dbo.tblNoteStore.ID
AND dbo.tblNoteEntities.NoteGUID = dbo.tblNoteStore.ID
INNER JOIN dbo.lstNoteTypes
ON dbo.tblNoteStore.Type = dbo.lstNoteTypes.NoteTypeID
ON dbo.tblClaims_Claim.ClaimGuid = dbo.tblNoteEntities.AssociatedEntityGUID
ON dbo.tblUsers.UserGUID = dbo.tblNoteRecipients.UserGUID
ON tblQuotes_1.ControlGuid = dbo.tblNoteEntities.ControlGuid
LEFT OUTER JOIN dbo.tblMaxQuoteIDs
ON tblQuotes_1.QuoteID = dbo.tblMaxQuoteIDs.MaxQuoteID
LEFT OUTER JOIN dbo.tblInsureds
ON dbo.tblNoteEntities.AssociatedEntityGUID = dbo.tblInsureds.InsuredGUID
然后我将任何不合适的ON条件移动到正确的位置,如果我可以在不破坏查询逻辑的情况下执行它。在这种情况下,如果没有一些重要的分析,我就无法做到。
注意:老实说,我讨厌这种类型的连接序列,如果你知道表和关系,你可以将它重新组织成一个简单的连接列表,而不是奇怪的嵌套连接结构。但这取决于两件重要的事情:
即使是现在,在我使用的最新版本的SQL Server(2014)中,也有一些查询可以通过在JOIN列表中移动表引用来优化。如果这就是将列表重组为此嵌套结构的原因,则可能会通过撤消特殊组织严重损害性能。当然,如果这是在最初的SQL Server版本中编写的,您可能需要解开这些联接,以查看查询优化器现在是否能很好地处理此结构。
永远不要低估前任的愚蠢(例如,访问The Daily WTF并浏览几分钟。)如果数据结构可以以需要笨拙和非规范化JOIN的方式相关联,将以这种方式相关。我还没有真正看到这个原因得到验证,但我知道在某些地方有一些数据结构需要这个。
答案 1 :(得分:1)
如果可读性是您的目标,那么值得注意的是您根本不需要嵌套或RIGHT JOIN。以下
少了不必要的字符和行
SELECT * FROM dbo.tblNoteStore nt_str JOIN dbo.lstNoteTypes nt_typ ON nt_str.[Type] = nt_typ.NoteTypeID JOIN dbo.tblNoteDiaries nt_dia ON nt_str.ID = nt_dia.NoteGUID JOIN dbo.tblNoteEntities entit ON nt_str.ID = entit.NoteGUID JOIN dbo.tblNoteEntries entri ON nt_str.ID = entri.NoteGUID and nt_dia.EntryGUID = entri.ID and entit.NoteGUID = entri.NoteGUID LEFT JOIN dbo.tblNoteRecipients recip ON entri.ID = recip.EntryGUID LEFT JOIN dbo.tblUsers usr ON recip.UserGUID = usr.UserGUID LEFT JOIN dbo.tblInsureds insur ON entit.AssociatedEntityGUID = insur.InsuredGUID LEFT JOIN dbo.tblClaims_Claim claim ON entit.AssociatedEntityGUID = claim.ClaimGUID LEFT JOIN dbo.tblQuotes qts_1 ON entit.ControlGUID = qts_1.ControlGUID LEFT JOIN dbo.lstLines lines ON qts_1.LineGUID = lines.LineGUID LEFT JOIN dbo.tblMaxQuoteIDs max_qt ON qts_1.QuoteID = max_qt.MaxQuoteId LEFT JOIN dbo.tblQuotes qts_2 ON claim.ControlNo = qts_2.ControlNo ;