Организовать группы агрегированных данных в заранее определенный список строк вместо всех точек данных в виде отдельных столбцов - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь создать набор данных в SQL, который скомпилирует результаты для программы лечения.

Я хочу показать частоту каждого уровня риска в разбивке по категориям, например:

enter image description here

SQL для это выглядит так со вставленными несмысленными фиктивными данными:

Select *
From 
 ( VALUES 
  ('Total Enrollments',5,9,3,2), 
  ('Total Successful',2,7,5,9),
  ('Total Failures',9,6,2,1),
  ('Failure - Drug Tests',2,1,4,7),
  ('Failure - Attendance Issues',2,6,9,2),
  ('Failure - Non-Payment',0,4,5,9),
  ('Failure - Other',3,9,3,1)
  ) t1 (Category,Low,Moderate,High,VeryHigh)

Конечная цель - импортировать данные в построитель отчетов SSRS и, возможно, PowerBI в будущем, и я бы лучше занялся агрегацией и организацией в SQL, так как я НЕНАВИЖУ иметь дело с выражениями в SSRS, и я хотел бы, чтобы данные были максимально переносимыми для экспорта в Excel, SSRS, PowerBI и т. д.

Производительность не является главной проблемой, так как этот отчет будет запускаться на нашем сервере отчетов один раз в месяц и автоматически доставляться списку лиц.

В настоящее время у меня есть запрос, в котором перечислены все Точки данных мне нужны, но все они являются отдельными столбцами, то есть организовать их в SSRS означало бы создание матрицы вручную.

Таким образом, запрос, который выбирает мой миллион столбцов, выглядит следующим образом:

enter image description here

</p>

<code>--DECLARE
    --@StartDate and @EndDate variables will be passed in by SSRS

SELECT

--Males Enrolled during period, by risk level:
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.EnrollmentDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Low' THEN 1 ELSE 0 END) AS MalesEnrollmentsLow,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.EnrollmentDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Moderate' THEN 1 ELSE 0 END) AS MalesEnrollmentsModerate,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.EnrollmentDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'High' THEN 1 ELSE 0 END) AS MalesEnrollmentsHigh,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.EnrollmentDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Very High' THEN 1 ELSE 0 END) AS MalesEnrollmentsVeryHigh,

--Males Successful during period, by risk level:
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.SuccessDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Low' THEN 1 ELSE 0 END) AS MalesSuccessLow,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.SuccessDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Moderate' THEN 1 ELSE 0 END) AS MalesSuccessModerate,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.SuccessDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'High' THEN 1 ELSE 0 END) AS MalesSuccessHigh,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.SuccessDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Very High' THEN 1 ELSE 0 END) AS MalesSuccessVeryHigh,

--Males Failed during period, by risk level:
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.FailDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Low' THEN 1 ELSE 0 END) AS MalesTotalFailLow,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.FailDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Moderate' THEN 1 ELSE 0 END) AS MalesTotalFailModerate,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.FailDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'High' THEN 1 ELSE 0 END) AS MalesTotalFaillHigh,
Sum(CASE WHEN clients.sex = 'M' and tblProgramResults.FailDate between @StartDate and @EndDate and AssessmentResults.PanelRiskLevel = 'Very High' THEN 1 ELSE 0 END) AS MalesTotalFailVeryHigh,

--Now break the failures down by reason:

--Males failed for FLDRUGTEST during period, by risk level:
SUM(CASE WHEN clients.sex = 'M' and tblProgramResults.FailDate between @StartDate and @EndDate and tblProgramResults.ProgramCompletedReasonCode = 'FLDRUGTEST' and AssessmentResults.PanelRiskLevel = 'Low' THEN 1 ELSE 0 END) AS MalesFailFLDRUGTESTLow,
SUM(CASE WHEN clients.sex = 'M' and tblProgramResults.FailDate between @StartDate and @EndDate and tblProgramResults.ProgramCompletedReasonCode = 'FLDRUGTEST' and AssessmentResults.PanelRiskLevel = 'Moderate' THEN 1 ELSE 0 END) AS MalesFailFLDRUGTESTModerate,
SUM(CASE WHEN clients.sex = 'M' and tblProgramResults.FailDate between @StartDate and @EndDate and tblProgramResults.ProgramCompletedReasonCode = 'FLDRUGTEST' and AssessmentResults.PanelRiskLevel = 'High' THEN 1 ELSE 0 END) AS MalesFailFLDRUGTESTHigh,
SUM(CASE WHEN clients.sex = 'M' and tblProgramResults.FailDate between @StartDate and @EndDate and tblProgramResults.ProgramCompletedReasonCode = 'FLDRUGTEST' and AssessmentResults.PanelRiskLevel = 'Very High' THEN 1 ELSE 0 END) AS MalesFailFLDRUGTESTVeryHigh

--There are 3 other 'failure' reasons...

FROM
tblProgramResults
--Get the gender info for each client
    OUTER APPLY ( SELECT
        Sex
        From tblClients
        WHERE tblClients.ClientID = tblProgramResults.ClientID
        ) Clients
--Get the assessment results for each client:
    OUTER APPLY ( SELECT
        PanelRiskLevel
        from tblAssessmentResults
        WHERE tblAssessmentResults.clientID = tblProgramResults.ClientID
            ) AssessmentResults

WHERE
--We're only interested in male clients for now, there will be a separate table for females as they are evaluated on a different risk scale
Clients.sex = 'M'
--We only want to look through programs that had an Enrollment, a Successful Completion, or a Failure during the specified date range:
and (tblProgramResults.EnrollmentDate between @StartDate and @EndDate or
    tblProgramResults.SuccessDate between @StartDate and @EndDate or 
    tblProgramResults.FailDate between @StartDate and @EndDate
    )
</code>

Итак, как мне взять результаты большого запроса и организовать его в красивую таблицу, такую ​​как первое изображение, вместо тонны столбцов ? Я пытаюсь вставить большой запрос в маленький, который создает таблицу, но я просто никуда не попадаю. Или я делаю это нелегко, когда есть что-то попроще?

1 Ответ

0 голосов
/ 27 марта 2020

если вы знаете, что все столбцы перед рукой, вы можете просто использовать функцию PIVOT в t- sql.

см. https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver15

Тем не менее, я бы позволил SSRS, Power Bi или чему-либо другому делать все это, так как эти данные хороши в повороте данных. Я бы переставил ваш запрос, хотя бы используя базовую группировку c. Запрос тоже будет намного проще. Возможно, я неправильно понял, поэтому добавьте образец данных из ваших таблиц базы данных и ожидаемого результата, и я обновлю ответ.

Взять, например, первую часть запроса, можно так же просто, как

* 1011. *

Это может быть легко изменено в SSRS, Power NI et c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...