T-SQL GroupBy с суммированными значениями счетчиков и средними значениями групп на основе диапазонов номеров - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть данные в двух таблицах, и я пытаюсь создать сводный запрос на основе диапазонов.Сводка предназначена для группировки на основе «зон GW» и в то же время суммирует значения счетчиков и отображает средние значения этих значений на 3 больше или меньше диапазонов.

Значение диапазона основано на pHводы.

например, Фильтры диапазонов 1: <6,5 Фильтр 2:> = 6,5 И <8,5 Фильтр 3:> = 8,5

1-я таблица ('1WorksTable') содержит имена "GWZone" (например, Zone1, Zone2, Zone3 (имеется несколько зон на уникальный 'WorksID'

WorksID GWZone
--------------
1       Zone1
2       Zone2
3       Zone2
4       Zone3
5       Zone3
6       Zone3
7       Zone3

2-я таблица ('1phTable') содержит значения pH, которые необходимо подсчитать, и их среднее значение, рассчитанное в одном из трех диапазонов (ph <7,> = 7 pH <8,5, pH> = 8,5)

LabResultsID    pH  WorksID
----------------------------
1               7       1
2               7       2
3               8       3
4               7       4
5               8       5
6               9       6
7              10       7

Стандартная группа T-SQL по запросу приводит к усреднению для всех значений и игнорирует три диапазона ph.

текущий результат:

GWZone  SummedCountWorksID  AvgpH
----------------------------------
Zone1   1                   7
Zone2   2                   7.5
Zone3   4                   8.5

Требуемый результат:

GWZone  SummedCountWorksID  AvgpH
----------------------------------
Zone1       1                   7
Zone2       1                   7
Zone3       1                   7
Zone2       1                   8
Zone3       1                   8
Zone3       2                   9.5

Может помочь разбиение на разделы или случай выбора диапазона в пределах выбора.

Код SQL длятаблицы и мой основной запрос:

CREATE TABLE [dbo].[1WorksTable]
(
    [WorksID] [int] IDENTITY(1,1) NOT NULL,
    [GWZone] [nvarchar](15) NULL,

    CONSTRAINT [PK_1WorksTable] 
        PRIMARY KEY CLUSTERED ([WorksID] ASC)
) ON [PRIMARY]

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[1phTable]
(
    [LabResultsID] [int] IDENTITY(1,1) NOT NULL,
    [pH] [float] NULL,
    [WorksID] [int] NULL,

    CONSTRAINT [PK_1Zones] 
        PRIMARY KEY CLUSTERED ([LabResultsID] ASC)
) ON [PRIMARY]
GO

SET IDENTITY_INSERT [dbo].[1WorksTable] ON 
GO

INSERT [dbo].[1WorksTable] ([WorksID], [GWZone]) 
VALUES (1, N'Zone1'), (2, N'Zone2'), 
       (3, N'Zone2'), (4, N'Zone3'),
       (5, N'Zone3'), (6, N'Zone3'),
       (7, N'Zone3')
GO

SET IDENTITY_INSERT [dbo].[1WorksTable] OFF
GO

SET IDENTITY_INSERT [dbo].[1phTable] ON 
GO

INSERT [dbo].[1phTable] ([LabResultsID], [pH], [WorksID]) 
VALUES (1, 7, 1), (2, 7, 2), (3, 8, 3),
       (4, 7, 4), (5, 8, 5), (6, 9, 6), (7, 10, 7)
GO

SET IDENTITY_INSERT [dbo].[1phTable] OFF
GO

Неудачная группа по запросу выглядит следующим образом:

SELECT        
    dbo.[1WorksTable].GWZone, 
    COUNT(dbo.[1phTable].WorksID) AS CountWorksID, 
    AVG(dbo.[1phTable].pH) AS AvgpH
FROM
    dbo.[1WorksTable] 
INNER JOIN
    dbo.[1phTable] ON dbo.[1WorksTable].WorksID = dbo.[1phTable].WorksID
GROUP BY 
    dbo.[1WorksTable].GWZone

Любые идеи, которые могут помочь мне заставить этот запрос работать по мере необходимости.

Спасибо за потраченное время!

Создание базового представления со всеми данными о pH устраняет необходимость вмежду таблицами, которые делают SQL более сложным.

SELECT        dbo.[1WorksTable].GWZone, dbo.[1phTable].WorksID, dbo.[1phTable].pH
FROM            dbo.[1phTable] INNER JOIN
                         dbo.[1WorksTable] ON dbo.[1phTable].WorksID = dbo.[1WorksTable].WorksID
GROUP BY dbo.[1WorksTable].GWZone, dbo.[1phTable].pH, dbo.[1phTable].WorksID

Частичное решение дает структуру группы и в качестве альтернативы отображает диапазоны.

SELECT        TOP (100) PERCENT GWZone, pH, COUNT(WorksID) AS Observations
FROM            (SELECT        CASE WHEN pH BETWEEN 0 AND 6.5 THEN '<=6.5' WHEN pH >= 6.5 AND pH < 8.5 THEN '>=6.5 and <8.5' ELSE '>=8.5' END AS pH, WorksID, GWZone
                          FROM            dbo.ParentView) AS t
GROUP BY pH, GWZone
ORDER BY GWZone, pH

Это приводит к такому результату;

Zone    pH Range    Sum(Count(WorksID)) 
Zone1   <6.5             1
Zone2   <6.5             1
Zone2   >=6.5 and <8.5   1
Zone3   <6.5             1
Zone3   >=6.5 and <8.5   1
Zone3   >=8.5            2

Единственное, чего не хватает сейчас, - это вычисления средних значений pH для каждой строки.

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Я подозреваю, что вам нужно включить выражение case в partition by из over() clause

select *
      , CASE
            WHEN pH BETWEEN 0 AND 6.5 THEN '<=6.5'
            WHEN pH >= 6.5 AND pH < 8.5 THEN '>=6.5 and <8.5'
            ELSE '>=8.5'
        END AS ph_range
      , avg(pH) over(partition by GWZone, CASE
                        WHEN pH BETWEEN 0 AND 6.5 THEN 1
                        WHEN pH >= 6.5 AND pH < 8.5 THEN 2
                        ELSE 3 END) avg_pH
FROM [1WorksTable
INNER JOIN  [1phTable] ON [1WorksTable].WorksID = [1phTable].WorksID
ORDER BY pH, GWZone

Этот запрос выдает (из ваших выборочных данных) следующее:

      WorksID   GWZone   LabResultsID   pH   WorksID      ph_range      avg_pH  
 --- --------- -------- -------------- ---- --------- ---------------- -------- 
  1         1   Zone1               1    7         1   >=6.5 and <8.5        7  
  2         2   Zone2               2    7         2   >=6.5 and <8.5      7.5  
  3         4   Zone3               4    7         4   >=6.5 and <8.5      7.5  
  4         3   Zone2               3    8         3   >=6.5 and <8.5      7.5  
  5         5   Zone3               5    8         5   >=6.5 and <8.5      7.5  
  6         6   Zone3               6    9         6   >=8.5               9.5  
  7         7   Zone3               7   10         7   >=8.5               9.5  

Я не уверен, как именно вы получите желаемый результат, но, как вы видите выше, можно рассчитать среднее значение по желаемым диапазонам.

также см .: http://rextester.com/DRS47751

0 голосов
/ 21 сентября 2018

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

SELECT      [1WorksTable].GWZone, 
            COUNT(1) OVER(PARTITION BY [1WorksTable].GWZone ORDER BY [1phTable].WorksID) AS CountWorksID, 
            CAST(AVG([1phTable].pH) AS DECIMAL(10,2)) AS AvgpH
FROM        [1WorksTable] 
INNER JOIN  [1phTable] ON [1WorksTable].WorksID = [1phTable].WorksID
GROUP BY    [1WorksTable].WorksID,
            [1WorksTable].GWZone,
            [1phTable].WorksID
ORDER BY    AvgpH, 
            GWZone
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...