如何缩小SQL查询结果的范围?

时间:2019-11-21 03:58:37

标签: sql sql-server

对于我的大型SQL类项目,我正在基于《魔兽世界经典》中的角色类创建数据库。 8个种族,9个职业,每个职业3个规格,每个规格都扮演特定角色(近战伤害,法术伤害,治疗,坦克,宠物)。

我基于所有这些创建了表,并添加了假玩家,并且数据库显示得非常漂亮。我的问题是运行查询。如果我只想寻找治疗者,那么当我只想要具有纪律,圣洁或恢复规范的角色时,它将在数据库中提取每个牧师,圣骑士,萨满和德鲁伊。

这是我的字符类表代码:

CREATE TABLE TOONCLASS (
ClassName   Char(10)    NOT NULL,
ClassType   Char(15)    NOT NULL, 
ArmorClass  Char(10)    NOT NULL,
Restriction Char(15)    NULL,
CONSTRAINT  ClassPK     PRIMARY KEY(ClassName),
CONSTRAINT  ClassValues CHECK (ClassName IN ('Druid', 'Hunter', 'Mage',
                'Paladin', 'Priest', 'Rogue', 'Shaman',
                'Warlock', 'Warrior')),
CONSTRAINT  ClassType   CHECK (ClassType IN ('Melee', 'Spellcaster', 'Hybrid')),
CONSTRAINT  TypeGroups  CHECK (
                (ClassName IN ('Druid', 'Shaman', 'Paladin') AND ClassType = 'Hybrid')
                OR (ClassName IN ('Mage', 'Priest', 'Warlock') AND ClassType = 'Spellcaster')
                OR (ClassName IN ('Hunter', 'Rogue', 'Warrior') AND ClassType = 'Melee')), 

CONSTRAINT  ArmorType   CHECK (ArmorClass IN ('Cloth', 'Leather', 'Mail', 'Plate')),
CONSTRAINT  ArmorGroups CHECK(
                (ClassName IN ('Mage', 'Priest', 'Warlock') AND ArmorClass = 'Cloth')
                OR (ClassName IN ('Druid', 'Rogue') AND ArmorClass = 'Leather')
                OR (ClassName IN ('Hunter', 'Shaman') AND ArmorClass = 'Mail')
                OR (ClassName IN ('Paladin', 'Warrior') AND ArmorClass = 'Plate')),
CONSTRAINT  ClassRestrict   CHECK (Restriction IN ('Alliance Only', 'Horde Only', NULL)),
CONSTRAINT  RestrictGroups  CHECK (
                (ClassName = 'Paladin' AND Restriction = 'Alliance Only')
                OR (ClassName = 'Shaman' AND Restriction = 'Horde Only')
                OR (Restriction = NULL)),
);

这是我的规格表代码:

CREATE TABLE TOONSPEC(
SpecName    Char(20)    NOT NULL,
ClassName   Char(10)    NOT NULL,
SpecRole    Char(20)    NOT NULL,
CONSTRAINT  SpecPK      PRIMARY KEY (SpecName),
CONSTRAINT  ClassFK     FOREIGN KEY (ClassName)
                REFERENCES TOONCLASS (ClassName),
CONSTRAINT  RoleGroups  CHECK (
                (SpecName IN ('Discipline', 'Holy(Pa)', 'Holy(Pr)', 'Restoration(Dr)', 
                'Restoration(Sh)') AND SpecRole = 'Healing')
                OR (SpecName IN ('Feral(Cat)', 'Marksmanship', 'Survival', 'Retribution', 
                'Assassination', 'Outlaw', 'Subtlety', 'Enhancement', 'Arms', 'Fury')
                AND SpecRole = 'Melee Damage')
                OR (SpecName IN ('Beast Mastery', 'Demonology') AND SpecRole = 'Pet')
                OR (SpecName IN ('Balance', 'Arcane', 'Fire', 'Frost', 'Shadow',
                'Elemental', 'Affliction', 'Destruction') AND SpecRole = 'Spell Damage')
                OR (SpecName IN ('Feral(Bear)', 'Protection(Pa)', 'Protection(Wa)') AND SpecRole = 'Tank')),
CONSTRAINT  SpecGroups  CHECK(
                (SpecName IN ('Balance', 'Feral(Bear)', 'Feral(Cat)', 'Restoration(Dr)') AND ClassName = 'Druid')
                OR (SpecName IN ('Beast Mastery', 'Marksmanship', 'Survival') AND ClassName = 'Hunter')
                OR (SpecName IN ('Arcane', 'Fire', 'Frost') AND ClassName = 'Mage')
                OR (SpecName IN ('Holy(Pa)', 'Protection(Pa)', 'Retribution') AND ClassName = 'Paladin')
                OR (SpecName IN ('Discipline', 'Holy(Pr)', 'Shadow') AND ClassName = 'Priest')
                OR (SpecName IN ('Assassination', 'Outlaw', 'Subtlety') AND ClassName = 'Rogue')
                OR (SpecName IN ('Elemental', 'Enhancement', 'Restoration(Sh)') AND ClassName = 'Shaman')
                OR (SpecName IN ('Affliction', 'Demonology', 'Destruction') AND ClassName = 'Warlock')
                OR (SpecName IN ('Arms', 'Fury', 'Protection(Wa)') AND ClassName = 'Warrior')),
 );

这是我的查询:

SELECT TOON.ToonName, TOON.CharLevel, TOON.ClassName, TOON.SpecName, 
TOONSPEC.SpecRole, TOONRACE.Faction
FROM TOON
INNER JOIN TOONSPEC ON TOON.ClassName=TOONSPEC.ClassName
INNER JOIN TOONRACE ON TOON.Race=TOONRACE.RaceName
WHERE SpecRole = 'Healing';

编辑:以下是查询结果。我忘记提到某些结果由于某些原因是重复的,因此我也欢迎提出任何建议:

enter image description here

我不知道问题出在查询还是表结构。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

INNER JOIN TOONSPEC ON TOON.ClassName=TOONSPEC.ClassName

您正在将SpecName存储在TOONTOONSPEC中,但是在过滤时没有使用它。您需要在过滤子句中添加AND

INNER JOIN TOONSPEC ON TOON.ClassName=TOONSPEC.ClassName AND TOON.SpecName = TOONSPEC.SpecName

或者,如果SpecName在类之间是唯一的,那么

INNER JOIN TOONSPEC ON TOON.SpecName = TOONSPEC.SpecName