2011-10-04 77 views
0

我是SQL中的Noob。SQL简单内部加入

伊夫3表:

TB_ITEM 
{ 
    TB_ITEM_ID int primary key, 
    TB_ITEM_CAT_ID int, 
    TB_ITEM_SUBCAT_ID int, 
    TB_ITEM_NAME varchar(350) 
    add constraint FK_ITEM_CAT foreign key(TB_ITEM_CAT_ID) 
    references TB_ITEM_CAT(TB_ITEM_CAT_ID), 
    add constraint FK_ITEM_SUBCAT foreign key(TB_ITEM_SUBCAT_ID) 
    references TB_ITEM_SUBCAT(TB_ITEM_SUBCAT_ID) 
} 
TB_ITEM_CAT 
{ 
    TB_ITEM_CAT_ID int primary key, 
    TB_ITEM_CAT_NAME varchar(350) 
} 
TB_ITEM_SUBCAT 
{ 
    TB_ITEM_SUBCAT_ID int primary key, 
    TB_ITEM_CAT_ID int, 
    TB_ITEM_SUBCAT_NAME 
    add constraint FK_CAT foreign key(TB_ITEM_CAT_ID) 
    references TB_ITEM_CAT(TB_ITEM_CAT_ID) 
} 

TABLE “TB_ITEM” HAS 416个记录。

我用尽,请查询:

select a.TB_ITEM_NAME, b.TB_ITEM_CAT_NAME, c.TB_ITEM_SUBCAT_NAME from 
TB_ITEM a inner join 
TB_ITEM_CAT b on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID 
    inner join TB_ITEM_SUBCAT c 
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID 

和结果是:1162个结果

我的意思是:我只想检索从TB_ITEM那些416点的记录及其类别名字和子目录名称 来自TB_ITEM_CAT和TB_ITEM_SUBCAT

此查询是错误的吗?为什么1162记录只代替416?

任何意识?

+0

如果'TB_ITEM'有多行'TB_ITEM_SUBCAT_ID'具有相同的条目,那么它们将与'TB_ITEM_SUBCAT_NAME'中的相同名称的列匹配多次。乍一看,这可能是问题。 – 2011-10-04 21:36:55

+0

尝试在查询结尾添加一个由1,2,3组组成的组。问题可能是你有重复的行。 – 2011-10-04 21:43:22

+0

与分组,结果计数是1152. -10 – ozsenegal

回答

2

您需要确保TB_ITEM_SUBCAT正确连接,以避免重复

见,如果这个工程:

select a.TB_ITEM_NAME, b.TB_ITEM_CAT_NAME, c.TB_ITEM_SUBCAT_NAME from 
TB_ITEM a inner join 
TB_ITEM_CAT b on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID 
inner join TB_ITEM_SUBCAT c 
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID and a.TB_ITEM_CAT_ID = c.TB_ITEM_CAT_ID 
+0

哇!现在可行!我的意思是,问题是什么?你能解释一下吗? – ozsenegal

+0

我注意到TB_ITEM_SUBCAT表有一个TB_ITEM_CAT表的外键,这让我怀疑TB_ITEM_SUBCAT_ID可能不是表的主键。主键可能是TB_ITEM_CAT_ID和TB_ITEM_SUBCAT_ID的组合。所以来自TB_ITEM的连接应该检查两个列的相等性。您可以通过查看TB_ITEM_SUBCAT表中的数据来验证这一点。 –

3

TB_ITEM有两个FKS

add constraint FK_ITEM_CAT foreign key(TB_ITEM_CAT_ID) 
    references TB_ITEM_CAT(TB_ITEM_CAT_ID) 

add constraint FK_ITEM_SUBCAT foreign key(TB_ITEM_SUBCAT_ID) 
    references TB_ITEM_SUBCAT(TB_ITEM_SUBCAT_ID) 

而且你加入比赛

from 
TB_ITEM a inner join 
inner join TB_ITEM_CAT b 
on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID 

inner join TB_ITEM_SUBCAT c 
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID 

这意味着您的查询rowcount必须小于或等于表计数。

因此,这让下面的possiblities ...

  1. 你的表的计数不正确
  2. 的加入在查询中张贴不匹配,你想什么
  3. 您的联合中还有其他的东西,我们没有看到
  4. 您并未引用您认为自己的对象。 (也许是一个视图或同义词)
  5. 或者你的主键或外键不是你说的那些。例如您的密钥是复合密钥

尝试将模式名称(例如dbo.TB_ITEM)添加到from子句中的表中并重新检查其他表。

+0

不,我不这么认为。下面的答案适用于我 – ozsenegal

+0

我很高兴你解决了你的问题。我更新了我的答案,以包括你发布关于密钥的其他可能性不准确(Rajeev能够找出答案)。我留下这个答案的可能性,这可能有助于未来的人。此外,由于职位可能发生变化,您可能希望参考海报而不是“上面”或“下面”的答案。 –

1

发生了什么事情是在结果中它创建一个记录每次一个项目匹配一个类别/子类别。例如,如果项目A有3个类别,则结果将包括项目A的3个实例,并匹配每个类别。当然,这是由子类别表和复合,以及。如果一个项目有3个类别和2个子类别将返回6个结果!

如果你不关心哪个类别和/或子类别您选择一个特定的项目你可以做这样的事情:

select a.TB_ITEM_NAME, b.TB_ITEM_CAT_NAME, c.TB_ITEM_SUBCAT_NAME from 
TB_ITEM a inner join 
TB_ITEM_CAT b on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID 
    inner join TB_ITEM_SUBCAT c 
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID 
GROUP BY a.TB_ITEM_ID 

此外,如果你只是想每一个单个实例项目和逗号分隔的类别列表,子类,我觉得这样的事情应该工作:

select a.TB_ITEM_NAME, GROUP_CONCAT(b.TB_ITEM_CAT_NAME), GROUP_CONCAT(c.TB_ITEM_SUBCAT_NAME) from 
TB_ITEM a inner join 
TB_ITEM_CAT b on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID 
    inner join TB_ITEM_SUBCAT c 
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID 
GROUP BY a.TB_ITEM_ID 

我希望这可以帮助你理解!