SQL查询中的不同值 - 高级

时间:2011-04-01 14:50:31

标签: sql sql-server

我已经搜索过高低,并且已经尝试了几个小时来操纵其他各种看似合适的查询,但我没有任何快乐。

我正在尝试加入Microsoft SQL Server 2005中的几个表,其中一个示例是:

Company Table (Comp_CompanyId, Comp_Name)
GroupCode_Link Table (gcl_c_groupcodelinkid, gcl_c_groupcodeid, gcl_c_companyid)
GroupCode Table (grp_c_groupcodeid, grp_c_groupcode, grp_c_name)
ItemCode Table (itm_c_itemcodeid, itm_c_name, itm_c_itemcode, itm_c_group)
ItemCode_Link Table (icl_c_itemcodelinkid, icl_c_companyid, icl_c_groupcodeid, icl_c_itemcodeid)

我正在使用链接表将一个组与一个公司关联,一个项目与一个组关联,因此公司可以有多个组,每个组中有多个项目。

现在,我正在尝试创建一个高级查找功能,允许用户输入例如项目代码,结果应该显示那些拥有该项目的公司,听起来很简单!

但是,我没有做对,如果我使用以下查询'如果公司有此项目或此项目,显示它的名称',我让公司在结果集中出现两次,每个项目一次

我需要的是能够说:

“显示包含这些项目的公司列表(仅显示每家公司一次!)”

我已经开始使用COUNT,DISTINCT和HAVING,但由于我的查询知识不合适,所以每次都失败了!

4 个答案:

答案 0 :(得分:2)

首先,根据您的描述,您的E-R(实体关系)模型可能会出现问题。您的描述告诉我您的E-R模型看起来像这样:

original E-R model

关联实体(CompanyGroup,GroupItem)用于实现多对多关系(因为关系数据库不直接支持多对多关系)。

如果一个组可以存在于多个公司中,或者一个项目存在于多个组中,则没有错。似乎更有可能的是,每个集团都是特定于公司的(我可以看到多个公司和/或集团中存在的项目:不止一家公司零售,例如,Cuisinart食品加工商)。如果是这种情况,更好的E-R模型将使每个组成为依赖实体,其公司ID是其主键的组成部分。它是一个依赖实体,因为该组没有独立存在:它由其母公司/代表创建并存在。如果公司离开,与之相关的团体就会消失。没有你的E-R模型看起来像这样:

simplified E-R model

由此,我们可以编写您需要的查询:

select *
from Company c
where exists ( select *
               from GroupItem gi
               where gi.ItemID in ( desired-itemid-1 , ... , desired-itemid-n )
                 and gi.CompanyID = c.CompanyID
             )

如您所见,依赖实体是一个强大的东西。由于密钥传播,查询往往变得更简单。使用原始数据模型,查询会更复杂一些:

select *
from Company c
where exists ( select *
               from CompanyGroup cg
               join GroupItem    gi on gi.GroupId = cg.GroupID
               where gi.ItemID in ( desired-itemid-1 , ... , desired-itemid-n )
                 and cg.CompanyID = c.CompanyID
             )

干杯!

答案 1 :(得分:1)

SELECT  *
FROM    company c
WHERE   (
        SELECT  COUNT(DISTINCT icl_c_itemcodeid)
        FROM    GroupCode_Link gl
        JOIN    ItemCode_Link il
        ON      il.icl_c_groupcodeid = gcl_c_groupcodeid
        WHERE   gl.gcl_c_companyid = c.Comp_CompanyId
                AND icl_c_companyid = c.Comp_CompanyId
                AND icl_c_itemcodeid IN (@Item1, @Item2)
        ) >= 2

如果您想要“任何项目”而不是“所有项目”,请将>= 2替换为>= 1

答案 2 :(得分:0)

如果您需要展示具有item1和item2的公司,您可以使用Quassnoi的答案。

如果您需要展示具有item1 OR item2的公司,那么您可以使用:

SELECT  
   *
FROM    
   company
WHERE EXISTS 
(
   SELECT
      icl_c_itemcodeid
   FROM
      GroupCode_Link
   INNER JOIN
      ItemCode_Link 
         ON icl_c_groupcodeid = gcl_c_groupcodeid
         AND icl_c_itemcodeid IN (@item1, @item2)
   WHERE   
      gcl_c_companyid = company.Comp_CompanyId
   AND 
      icl_c_companyid = company.Comp_CompanyId
)

答案 3 :(得分:0)

我会写下面的代码:

SELECT
    c.Comp_Name
FROM
    Company AS c
WHERE
    EXISTS (
        SELECT
            1
        FROM
            GroupCode_Link AS gcl
        JOIN
            ItemCode_Link AS icl
        ON
            gcl.gcl_c_groupcodeid = icl.icl_c_groupcodeid
        JOIN
            ItemCode AS itm
        ON
            icl.icl_c_itemcodeid = itm.itm_c_itemcodeid
        WHERE
            c.Comp_CompanyId = gcl.gcl_c_companyid
        AND
            itm.itm_c_itemcode IN (...) /* here provide list of one or more Item Codes to look for */
    );

但是我看到ItemCode_Link中有一个icl_c_companyid列,所以不需要使用GroupCode_Link表吗?