按分期分组

时间:2012-03-05 12:51:51

标签: sql sql-server group-by grouping

我有3个表agencytbl,branchtbl和tourtbl。我正在尝试计算与代理商相关的总分支数和与分支机构相关的总访问量。这是我的疑问:

SELECT  dbo.AgencyTbl.AgencyName AS [LIST OF EACH AGENCY],
(select COUNT(*) from BranchTbl where BranchTbl.AgencyID = AgencyTbl.AgencyID) as [NO OF BRANCHES],
(SELECT COUNT(*) AS Expr1 FROM dbo.TourTbl 
WHERE      (dbo.BranchTbl.BranchID = BranchID)) AS [NO TOURS EVER]

FROM dbo.AgencyTbl INNER JOIN dbo.BranchTbl ON dbo.AgencyTbl.AgencyID = dbo.BranchTbl.AgencyID 
GROUP BY AgencyTbl.AgencyName, AgencyTbl.AgencyID, dbo.BranchTbl.BranchID
order by AgencyTbl.AgencyName

但如果我运行这个,我会重复同一个机构,因为group by by branchid如下:

 this estate agent  12  0
 this estate agent  12  0
 this estate agent  12  0
 this estate agent  12  0
 this estate agent  12  0
 this estate agent  12  0
 this estate agent  12  0
 this estate agent  12  2
 this estate agent  12  0
 this estate agent  12  0
 this estate agent  12  0
 this estate agent  12  0
    next agency     47  2
   next agency      47  4
   next agency      47  1
   next agency      47  1

我如何只列出一个代理商和属于该代理商的分支机构总数,然后列出属于该分支机构的旅行总数,而不是重复代理机构名称。

2 个答案:

答案 0 :(得分:2)

我假设“属于该分支的旅行总数”是指“属于该机构的所有分支”的旅行总数?

如果是这样,您可以使用这些方法中的任何一种。

方法1:仅使用子查询,不要加入BranchTbl

SELECT  dbo.AgencyTbl.AgencyName AS [LIST OF EACH AGENCY],
        ( SELECT COUNT(*)
            FROM BranchTbl
           WHERE AgencyID = AgencyTbl.AgencyID
        ) AS [NO OF BRANCHES],
        ( SELECT COUNT(*)
            FROM dbo.TourTbl
           WHERE BranchID IN
                  ( SELECT BranchID
                      FROM dbo.BranchTbl
                     WHERE AgencyID = AgencyTbl.AgencyID
                  )
        ) AS [NO TOURS EVER]
  FROM dbo.AgencyTbl
 GROUP
    BY AgencyTbl.AgencyName,
       AgencyTbl.AgencyID
 ORDER
    BY AgencyTbl.AgencyName
;

方法2:仅使用联接,不要使用子查询:

SELECT dbo.AgencyTbl.AgencyName AS [LIST OF EACH AGENCY],
       COUNT(DISTINCT dbo.BranchTbl.BranchID) AS [NO OF BRANCHES],
       COUNT(dbo.TourTbl.BranchTbl) AS [NO TOURS EVER]
  FROM dbo.AgencyTbl
  LEFT
  JOIN dbo.BranchTbl
    ON dbo.BranchTbl.AgencyID = dbo.AgencyTbl.AgencyID
  LEFT
  JOIN dbo.TourTbl
    ON dbo.TourTbl.BranchID = dbo.BranchTbl.BranchID
 GROUP
    BY AgencyTbl.AgencyName
 ORDER
    BY AgencyTbl.AgencyName
;

还有一些其他方法 - 例如,您可以加入BranchTbl,但使用SUM(SELECT COUNT(*) FROM ...)来获取游览次数 - 但我认为以上是最清楚的。

[免责声明:我尚未测试上述任何一种查询。]

答案 1 :(得分:1)

首先,您不需要一些子查询,因为您已经在进行JOIN。最重要的是,您需要按更多列进行分组。试试这个:

SELECT  dbo.AgencyTbl.AgencyName AS [LIST OF EACH AGENCY],
        COUNT(*) AS [NO OF BRANCHES],
        COUNT(dbo.TourTbl.*) AS [NO TOURS EVER],
        COUNT(CASE WHEN YEAR(DT_Started) = YEAR(GETDATE()) THEN dbo.TourTbl.BranchID ELSE NULL END)  [NO OF TOURS YTD (Year To Date)]
FROM dbo.AgencyTbl 
INNER JOIN dbo.BranchTbl 
ON dbo.AgencyTbl.AgencyID = dbo.BranchTbl.AgencyID 
LEFT JOIN dbo.TourTbl 
ON dbo.BranchTbl.BranchID = dbo.TourTbl.BranchID
GROUP BY AgencyTbl.AgencyName
ORDER BY AgencyTbl.AgencyName