从多个内部联接中获取数据

时间:2014-12-26 08:47:41

标签: sql-server count group-by inner-join aggregate-functions

我有以下表格。

表: PollingBooth PBId是主键。

PBID  | PBName |pdivID      
-----------------------
1     | Jaya PB | 1

2     | SP PB   | 1

表:PollingDivision - pdID是主键。

----------------

pdID  |pdName
------------------
1     | Homagama 

2     | Maharagama  

表:ElectionOfficial -EoId是主键。

----------------
EoID   |EoName
---------------
1      | Sam

2      | Ram

3      | Feston

表:Election- elecID是主键。

--------------------------------------
elecID    | ElecName
--------------------------------------
1         | Presidential Election 2013

2         | General Election 2014

表:PollingBoothElection- pbID和elecID列都构成主键

--------------------------------
pbID   | elecID |numofEOs
--------------------------------
1      | 1      | 2

2      | 1      | 3

表:PollingBoothElectionOfficial。所有三列都是组合的主键。

----------------------------------

pbID   | elecID   | eOfficialID 
----------------------------------

1      | 1        |1

1      | 1        |2

我想选择特定PollingDivision的所有PollingBooth名称,其中特定选举的每个PollingBooth的eoID计数小于特定选举的允许选举官员数量。

换句话说,我想选择所有PollingBooth名称,其中给定pbID和elecID的PollingBoothElectionofficial表中所有eOfficialID的计数小于相同eleID和pbID的PollingBoothElection的numberofEOs的值,我想要为特定PollingDivision的所有投票站执行此操作。

这是我尝试过的。

   SELECT PB.PBName, COUNT(PBEO.eOfficialID)
   FROM PollingBoothElection PBE
   INNER JOIN PollingBooth PB ON PBE.pbID=PB.PBID
   INNER JOIN PollingDivision PD ON PB.pdivID=PD.pdID
   INNER JOIN PollingBoothElectionOfficial PBEO ON PBE.elecID=PBEO.elecID 
   AND PBE.pbID=PBEO.pboothID
   WHERE PBE.elecID=1 AND PD.pdName='Homagama' AND PBE.numOfEO>(SELECT COUNT(PBEO.eOfficialID))
   GROUP BY PB.PBName; 

但是这表示我不能在where子句中包含聚合函数。那么如何在PollingBoothElectionOfficial表中检查每个投票站的选举官员在特定选举中的数量不超过PollingBoothElection表中允许的选举官员数量。

有没有办法可以通过IF ELSE语句实现这一目标?

任何帮助都会很棒。 提前谢谢。

2 个答案:

答案 0 :(得分:2)

如错误中所述,您无法使用aggregate子句中的where函数来过滤结果集。

将该条件从Where clause移至Having Clause,用于搜索groupaggregate的条件

SELECT PB.PBName,
       Count(PBEO.eOfficialID)
FROM   PollingBoothElection PBE
       INNER JOIN PollingBooth PB
               ON PBE.pbID = PB.PBID
       INNER JOIN PollingDivision PD
               ON PB.pdivID = PD.pdID
       INNER JOIN PollingBoothElectionOfficial PBEO
               ON PBE.elecID = PBEO.elecID
                  AND PBE.pbID = PBEO.pboothID
WHERE  PBE.elecID = 1
       AND PD.pdName = 'Homagama'
GROUP  BY PB.PBName,PBE.numOfEO
HAVING Count(PBEO.eOfficialID) < PBE.numOfEO 

答案 1 :(得分:0)

虽然上面的解决方案可以解决您的错误,但是您正在使用的连接和条件不正确,并且方法计数使用两次我们可以避免,并且内部连接之间的“AND”条件不是必需的(您可以把它放在where子句中)。另外你没有检查lkup表可能会加入条件,其中从lkup表中删除的数据可能会给出错误的输出。我对连接和条件的建议是,检查出来:))

SELECT 
    PB.PBName AS BoothName,
    Count(PBEO.eOfficialID) AS EoTotalCount
FROM
    PollingBooth PB
    INNER JOIN pollingDivision pdiv ON pdiv.pdID = pb.pdivID
    INNER JOIN pollingBothElection pbelec ON pbelec.pbID = pb.pbID
    INNER JOIN Election election ON election.elecID = pbelec.elecID
    INNER JOIN PollingBoothElectionOfficial pBothElecO ON pBothElecO.pbID = PB.PBID
    INNER JOIN ElectionOfficial eo ON eo.EoID = pBothElecO.eOfficialID
WHERE
    pbelec.elecID = 1
    AND pdiv.pdID = 1
GROUP BY
    pb.pbID,
    pbelec.numOfEO
HAVING 
    EoTotalCount < pbelec.numOfEO