简体   繁体   English

SQL获取按列分组的几行的计数

[英]SQL getting counts for several rows grouped by a column

I am trying to count multiple individual rows for each column. 我正在尝试为每一列计算多个单独的行。 Below is an example of what I am trying to accomplish. 以下是我要完成的示例。

select (select top 1 name
          from chap
         where chap.chp_id = CHS.chp_id) as Chap,
       (select count(*)
          from CHS,
               chap 
         where O_TYPE = 'PRESIDENT'
           and chs.chp_id = chap.chp_id) as Presidents,
       (select count(*)
          from CHS 
         where O_TYPE = 'VICEPRESIDENT') as VicePresidents,
       (select count(*)
          from CHS 
         where OFFICER_TYPE = 'CORRSECRETARY') as CorrespondinSecretaries,
       (select count(*)
          from CHS 
         where O_TYPE = 'RECORDINGSECRETARY') as RecordingSecretaries,
       (select count(*)
          from CHS 
         where O_TYPE = 'TREASURER') as Treasurers,
       (select count(*)
          from CHS 
         where O_TYPE = 'ADVISOR'
           and ADV_CODE = 'B') as ChiefAdvisors,
       (select count(*)
          from CHS 
         where O_TYPE = 'ADVISOR'
           and ADV_CODE <> 'B') as ChiefAdvisors
from CHS
where O_TYPE in ('PRESIDENT', 'VICEPRESIDENT', 'CORRSECRETARY', 'RECORDINGSECRETARY', 'TREASURER', 'ADVISOR')
  and Term_expire >= DateAdd(Day,DateDiff(Day,0,GetDate()),0)
  and Term_Begin <= DateAdd(Day,DateDiff(Day,0,GetDate()),0)
  and CHS.CHP_ID in (Select chp_id 
                            from chrs
                           where active = 'Y') 
Group by chs.CHP_ID

when I run this it totals each row with all of the records not just the records for that chapter. 当我运行它时,它会将所有记录总计在每一行中,而不仅仅是该章的记录。 Any suggestions? 有什么建议么?

Output Example 输出范例

AL A    247 264 247 250 246 235 739
AL B    247 264 247 250 246 235 739
AL G    247 264 247 250 246 235 739
AL D    247 264 247 250 246 235 739
AK A    247 264 247 250 246 235 739
AZ A    247 264 247 250 246 235 739
AZ B    247 264 247 250 246 235 739
AZ G    247 264 247 250 246 235 739

What I really want is 我真正想要的是

AL A 1 1 1 4 8 9 16
AL B 1 1 5 7 8 9 21

Consider replacing all subqueries as calculated columns with first name simply being a JOIN to main table. 考虑将所有子查询替换为具有第一名称的计算列,只需将其作为主表的JOIN For counts use conditional aggregation by summing the conditions. 对于计数,通过对条件求和来使用条件聚合。 Additionally, adjust the GROUP BY to include name and not unique id which may be reason for repetitious data. 此外,调整GROUP BY以包括名称而不是唯一ID,这可能是重复数据的原因。 Also, check term date ranges in WHERE as they appear to be redundant. 另外,在WHERE检查学期日期范围,因为它们似乎是多余的。

SELECT chap.name AS Chap,
       SUM(O_TYPE = 'PRESIDENT') AS Presidents,
       SUM(O_TYPE = 'VICEPRESIDENT') AS VicePresidents,
       SUM(OFFICER_TYPE = 'CORRSECRETARY') AS CorrespondingSecretaries,
       SUM(O_TYPE = 'RECORDINGSECRETARY') AS RecordingSecretaries,
       SUM(O_TYPE = 'TREASURER') AS Treasurers,
       SUM(O_TYPE = 'ADVISOR' AND ADV_CODE = 'B') AS ChiefAdvisors,
       SUM(O_TYPE = 'ADVISOR' AND ADV_CODE <> 'B') AS OtherAdvisors

FROM chap
INNER JOIN CHS ON chap.chp_id = CHS.chp_id
INNER JOIN chrs ON CHS.CHP_ID = chrs.CHP_ID AND active = 'Y'
WHERE O_TYPE IN ('PRESIDENT', 'VICEPRESIDENT', 'CORRSECRETARY', 
                 'RECORDINGSECRETARY', 'TREASURER', 'ADVISOR')
  AND Term_expire >= DATEADD(Day, DATEDIFF(Day, 0, GETDATE()), 0)
  AND Term_Begin <= DATEADD(Day, DATEDIFF(Day, 0, GETDATE()), 0)

GROUP BY chap.name

Conditional aggregation should do what you want. 有条件的聚合应该做您想要的。 In SQL Server, I would phrase this as: 在SQL Server中,我将其表述为:

SELECT chap.name AS Chap,
       SUM(CASE WHEN chs.O_TYPE = 'PRESIDENT' THEN 1 ELSE 0 END) AS Presidents,
       SUM(CASE WHEN chs.O_TYPE = 'VICEPRESIDENT' THEN 1 ELSE 0 END) AS VicePresidents,
       SUM(CASE WHEN chs.OFFICER_TYPE = 'CORRSECRETARY' THEN 1 ELSE 0 END) AS CorrespondingSecretaries,
       SUM(CASE WHEN chs.O_TYPE = 'RECORDINGSECRETARY' THEN 1 ELSE 0 END) AS RecordingSecretaries,
       SUM(CASE WHEN chs.O_TYPE = 'TREASURER' THEN 1 ELSE 0 END) AS Treasurers,
       SUM(CASE WHEN chs.O_TYPE = 'ADVISOR' AND ADV_CODE = 'B' THEN 1 ELSE 0 END) AS ChiefAdvisors,
       SUM(CASE WHEN chs.O_TYPE = 'ADVISOR' AND ADV_CODE <> 'B' THEN 1 ELSE 0 END) AS OtherAdvisors
FROM chap JOIN
     CHS
     ON chap.chp_id = CHS.chp_id JOIN
     chrs
     ON CHS.CHP_ID = chrs.CHP_ID AND 
WHERE chrs.active = 'Y' AND
      chap.O_TYPE IN ('PRESIDENT', 'VICEPRESIDENT', 'CORRSECRETARY', 
                      'RECORDINGSECRETARY', 'TREASURER', 'ADVISOR'
                     ) AND
     chap.Term_expire >= CONVERT(DATE, GETDATE()) AND
     chap.Term_Begin <= CONVERT(DATE, GETDATE())
GROUP BY chap.name;

Note that this also qualifies all column names and simplifies the date arithmetic. 请注意,这还可以限定所有列名并简化日期算术。

Please try this: 请尝试以下方法:

SELECT chap.Name AS [Chap]
    ,SUM(IIF(chs.O_TYPE = 'PRESIDENT',1,0)) AS [Presidents]
    ,SUM(IIF(chs.O_TYPE = 'VICEPRESIDENT',1,0)) AS [VicePresidents]
    ,SUM(IIF(chs.O_TYPE = 'CORRSECRETARY',1,0)) AS [CorrespondinSecretaries]
    ,SUM(IIF(chs.O_TYPE = 'RECORDINGSECRETARY',1,0)) AS [RecordingSecretaries]
    ,SUM(IIF(chs.O_TYPE = 'TREASURER',1,0)) AS [Treasurers]
    ,SUM(IIF(chs.O_TYPE = 'ADVISOR' AND chs.ADV_CODE = 'B',1,0)) AS [ChiefAdvisorsB]
    ,SUM(IIF(chs.O_TYPE = 'ADVISOR' AND chs.ADV_CODE <> 'B',1,0)) AS [ChiefAdvisorsNotB]
FROM chs
INNER JOIN chrs ON chrs.CHP_ID = chs.CHP_ID AND chrs.Active = 'Y' /*works as filter*/
INNER JOIN chap ON chap.CHP_ID = chs.CHP_ID
WHERE chs.O_TYPE IN ('PRESIDENT', 'VICEPRESIDENT', 'CORRSECRETARY', 'RECORDINGSECRETARY', 'TREASURER', 'ADVISOR')
    AND DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()),0) BETWEEN chs.Term_Begin AND chs.Term_expire
GROUP BY chap.Name
;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM