2011-04-01 81 views
2

我已搜查高和低,都試過了好幾個小時來操縱,似乎適合其它各種查詢,但我已經沒有喜悅。重複值 - 高級

我在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,但由於我的查詢知識無法勝任,所以每個都失敗了!

回答

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

+0

從性能的角度來看,「任何項目」,豈不是有意義的使用「存在」,而不是「計數」?如果這些數量龐大的桌子不算太慢? – kevev22 2011-04-01 16:11:07

+0

@ kevev22:'SQL Server'優化COUNT(*)> = 1','EXISTS'和'IN'到同一個計劃。 – Quassnoi 2011-04-01 16:11:59

+0

你必須用'> = 1'替換任何項目的'= 2'。 – kevev22 2011-04-01 16:12:08

0

如果你需要證明有ITEM1和ITEM2公司,你可以使用Quassnoi的答案。

如果你需要證明有ITEM1的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 
) 
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表?

2

首先,從你的描述,它聽起來就像你可能會與你的E-R(實體關係)模式的問題。你的描述告訴我,你的ER模型看起來是這樣的:

original E-R model

關聯實體(CompanyGroup,GroupItem)存在實現許多一對多的關係(因爲許多到許多不由關係數據庫直接支持)。

沒有錯,如果一組可以在多個企業或跨多個團體項目中存在。至少,每個小組似乎更有可能是特定於一家公司的(我可以看到跨多個公司和/或小組存在的項目:不止一家公司零售,例如Cuisinart食品加工商)。如果是這種情況,一個更好的E-R模型將使每個組具有一個依賴實體並且其CompanyID是其主鍵的組成部分。這是一個獨立的實體,因爲該集團沒有獨立的存在:它是由其母公司創建/代表併爲其存在。如果公司消失,與之綁定的集團就會消失。沒有您的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 
      ) 

乾杯!