我在两个表中都有数据,并且我试图基于范围生成摘要查询。该摘要旨在根据“ GWZones”进行分组,同时对计数值求和,并基于大于或小于3的范围显示这些值的平均值。
范围值基于水的pH值。
例如范围Filter1:<6.5 Filter2:> = 6.5 AND <8.5 Filter3:> = 8.5
第一个表('1WorksTable')包含“ GWZone”名称(例如Zone1,Zone2,Zone3(每个唯一的“ WorksID”有多个区域
WorksID GWZone
--------------
1 Zone1
2 Zone2
3 Zone2
4 Zone3
5 Zone3
6 Zone3
7 Zone3
第二张表('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平均值。
答案 0 :(得分:0)
我不确定您是如何根据所需结果来计算一些数字的,所以在这里我要暗中进行一些测试。希望以下查询能使您进一步了解所需结果的目标。
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
答案 1 :(得分:0)
我怀疑您需要在partition by
的{{1}}中加入一个case表达式
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
我不确定您如何准确地获得所需的结果,但是如您在上面看到的,可以通过所需的范围计算平均值。