SQL получает значения для нескольких строк, сгруппированных по столбцу - PullRequest
1 голос
/ 20 марта 2019

Я пытаюсь сосчитать несколько отдельных строк для каждого столбца. Ниже приведен пример того, чего я пытаюсь достичь.

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

когда я запускаю это, он суммирует каждую строку со всеми записями, а не только с записями для этой главы. Есть предложения?

Пример вывода

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

Что я действительно хочу, так это

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

Ответы [ 3 ]

0 голосов
/ 20 марта 2019

Условное агрегирование должно делать то, что вы хотите.В 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;

Обратите внимание, что это также определяет все имена столбцов и упрощает арифметику дат.

0 голосов
/ 21 марта 2019

Пожалуйста, попробуйте это:

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
;
0 голосов
/ 20 марта 2019

Подумайте о замене всех подзапросов в виде вычисляемых столбцов с первым именем , просто являющимся JOIN для основной таблицы.Для подсчета используйте условное агрегирование путем суммирования условий.Кроме того, настройте GROUP BY, указав имя , а не уникальный идентификатор, который может быть причиной повторяющихся данных.Кроме того, проверьте срок дат в диапазоне 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...