我在下面的查询中遇到了一些问题。我的所有用户都在一个名为ItemInstances
的表中,我的所有数据都包含在名为ItemPropertyValuesInt
,ItemPropertyValuesBool
的表中的用户中。
此查询正常工作,直到我添加IsBanned
查询。并非所有用户都在此表中有条目,因此只返回5个用户而不是300个。我的理解是LEFT JOIN
将是解决方案,但也许我误解了如何在此查询中写入此内容。
此查询的任何其他优化提示也欢迎,因为数据库是巨大的
SELECT ItemInstances.Id,
Relics.PropertyValue AS Hugo_Relics,
AllianceID.PropertyValue AS Hugo_AllianceID,
Faction.PropertyValue AS Hugo_Faction,
LevelXP.PropertyValue AS Hugo_Level,
WeeklyRelics.PropertyValue AS Hugo_WeeklyRelics,
UserName.PropertyValue AS Hugo_UserName,
ItemInstances.CreatorId,
IsBanned.PropertyValue
FROM dbo.ItemInstances
LEFT OUTER JOIN dbo.ItemPropertyValuesInt Faction
ON Faction.RecordId = ItemInstances.Id
LEFT OUTER JOIN dbo.ItemPropertyValuesInt LevelXP
ON LevelXP.RecordId = ItemInstances.Id
LEFT OUTER JOIN dbo.ItemPropertyValuesInt Relics
ON ItemInstances.Id = Relics.RecordId
LEFT OUTER JOIN dbo.ItemPropertyValuesInt AllianceID
ON ItemInstances.Id = AllianceID.RecordId
LEFT OUTER JOIN dbo.ItemPropertyValuesInt WeeklyRelics
ON WeeklyRelics.RecordId = ItemInstances.Id
LEFT OUTER JOIN dbo.ItemPropertyValuesString UserName
ON UserName.RecordId = ItemInstances.Id
LEFT OUTER JOIN dbo.ItemPropertyValuesBool IsBanned
ON IsBanned.RecordId = ItemInstances.Id
WHERE Relics.PropertyId = 541
AND AllianceID.PropertyId = 504
AND Faction.PropertyId = 520
AND LevelXP.PropertyId = 529
AND WeeklyRelics.PropertyId = 730
AND UserName.PropertyId = 554
AND IsBanned.PropertyId = 728
ORDER BY Hugo_Relics DESC
答案 0 :(得分:4)
如果在左连接表中没有匹配的记录,则需要在任何WHERE子句条件中考虑该记录。例如:
AND (IsBanned.PropertyId = 728 OR IsBanned.PropertyId IS NULL)
答案 1 :(得分:1)
即使你刚加入,你也在选择
AND IsBanned.PropertyId = 728
不在禁止表中的用户的isBanned.PropertyId为null
所以你没有选择它们。
答案 2 :(得分:1)
我对你的查询的意图并不十分清楚,但我觉得这应该是如何格式化的。
FROM dbo.ItemInstances
LEFT JOIN dbo.ItemPropertyValuesInt Faction
ON Faction.RecordId = ItemInstances.Id
AND Faction.PropertyId = 520
LEFT JOIN dbo.ItemPropertyValuesInt LevelXP
ON LevelXP.RecordId = ItemInstances.Id
AND LevelXP.PropertyId = 529
LEFT JOIN dbo.ItemPropertyValuesInt Relics
ON Relics.RecordId = ItemInstances.Id
AND Relics.PropertyId = 541
LEFT JOIN dbo.ItemPropertyValuesInt AllianceID
ON AllianceID.RecordId = ItemInstances.Id
AND AllianceID.PropertyId = 504
LEFT JOIN dbo.ItemPropertyValuesInt WeeklyRelics
ON WeeklyRelics.RecordId = ItemInstances.Id
AND WeeklyRelics.PropertyId = 730
LEFT JOIN dbo.ItemPropertyValuesString UserName
ON UserName.RecordId = ItemInstances.Id
AND UserName.PropertyId = 554
LEFT JOIN dbo.ItemPropertyValuesBool IsBanned
ON IsBanned.RecordId = ItemInstances.Id
AND IsBanned.PropertyId = 728
WHERE ItemInstances.Id = ?
Gordon Linoff的评论很好地解释了这一点。
LEFT JOIN b ON b.id = a.id AND b.value = x
--All records from [a] retained
--Only records from [b] where b.value = x LEFT JOIN'd to [a]
与
非常不同LEFT JOIN b ON b.id = a.id WHERE b.value = x
--Only records from [a] and [b] where [b].value = x are retained