尝试在sql server中查找总和的中位数

bn31dyow  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(398)

我正在努力找到我的电动汽车类每月的中位数。为此,我需要总结每个逻辑设备名称的所有事件。然而,这需要每月进行一次。我有两个查询第一个,我会贴在下面总结了所有的机器人每天的事件,但我需要进一步总结,使之成为每月的基础。我也需要这样做的基础上,每月数年。

select logicalDeviceName, Sum(Events) as consolidatedEvents, EVS, StartDate
From report.DisinfectionStatsCombined
group By LogicalDeviceName, EVS, StartDate
Order By EVS

结果就是这样
这是我的结果的一个例子,你们可以看到我需要一个单独的行是阿波罗和一个月的所有合并事件的总和
此外,这里是我的代码,试图用一个结果样本来计算中位数。

select logicalDeviceName, Sum(Events) as consolidatedEvents, EVS, StartDate,
PERCENTILE_CONT(0.5) within group (order by Sum(Events))
OVER (Partition BY year(StartDate),Month(StartDate),EVS) AS MedianCont
From report.DisinfectionStatsCombined
group By LogicalDeviceName, EVS, StartDate,Events
Order By EVS

正如您所看到的,结果远远不理想,合并事件的数字也变得不正确。我认为第一个查询的数字是正确的,但是这里的变化很大,为什么?
我再次尝试通过按每个逻辑设备名称汇总所有合并事件来计算中间值。所以每个月应该只有一个名字。然后,我将使用这些信息每月计算每辆电动汽车的中位数。有4种电动汽车类型,我将提供另一种类型的剪报。我觉得我可能要改变分组,以显示不同类型的电动汽车。理想情况下,我只希望它按月/年分组。日期可以追溯到2012年。
其他电动汽车示例图片
下面是一个什么样的样本,我希望我的期望结果是样本结果和数据

ecfdbz9o

ecfdbz9o1#

我对你目标的理解:
每月计算每个logicaldevicename的事件计数
计算每个logicaldevicename每月事件的中位数
计算每个EV每月事件的中位数
我的工作假设是,对于任何给定的logicaldevicename,只有一个匹配的EV。例如,当logicaldevicename值为“apollo”时,evs值将始终为“commercial”。
注意,我创建并填充了测试表以获得下面的屏幕截图。脚本包含在下面。
目标1:汇总每个logicaldevicename每月的事件数,以回答“阿波罗在2015年1月发生了多少事件?”。像这样的查询应该可以解决问题。将年和月的部分从日中分离出来,可以实现月的聚合:

SELECT 
      LogicalDeviceName
    , SUM(Events) [ConsolidatedEvents]
    , EVS
    , FORMAT(StartDate, 'yyyy/MM') [YearAndMonth]
FROM [Test]
GROUP BY 
      LogicalDeviceName
    , EVS
    , FORMAT(StartDate, 'yyyy/MM')
ORDER BY 
      YearAndMonth DESC
    , LogicalDeviceName


目标2:为每个logicaldevicename计算每月事件的中位数

SELECT DISTINCT
      LogicalDeviceName
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY Events) 
        OVER (PARTITION BY LogicalDeviceName, YEAR(StartDate), MONTH(StartDate)) [Median]
    , FORMAT(StartDate, 'yyyy/MM') [YearAndMonth]
FROM [Test]
ORDER BY [YearAndMonth] DESC, LogicalDeviceName


需要使用distinct,因为partition by为每条记录包含一行。还要注意的是,虽然这种语法更简单,但有可能更有效的方法来计算中值。
目标3:使用每个logicaldevicename事件的“合并”(总和)计算每个EV每月事件的中位数
在这里,我又一次对你想要实现的目标感到迷茫。如有进一步澄清,将予以更新。根据提供的前/后集截图编辑以下内容。在我脑海中,根据第一个查询构建cte是最简单的方法:

WITH Consolidated AS
(
    SELECT 
          LogicalDeviceName
        , SUM(Events) [ConsolidatedEvents]
        , EVS
        , FORMAT(StartDate, 'yyyy/MM') [YearAndMonth]
    FROM [Test]
    GROUP BY 
          LogicalDeviceName
        , EVS
        , FORMAT(StartDate, 'yyyy/MM')
)
SELECT DISTINCT
    EVS
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ConsolidatedEvents)
        OVER (PARTITION BY EVS, YearAndMonth) [Median]
    , YearAndMonth
FROM Consolidated
ORDER BY YearAndMonth DESC, EVS


测试表创建/填充脚本:

SET NOCOUNT ON
GO
CREATE TABLE [Test]
(
      LogicalDeviceName VARCHAR(64)
    , Events INT
    , EVS VARCHAR(16)
    , StartDate DATETIME2
)

GO

DECLARE @LDN_EVS_Pairs TABLE
(
      LDN VARCHAR(16)
    , EVS VARCHAR(16)
)

INSERT INTO @LDN_EVS_Pairs(LDN, EVS)
VALUES
      ('Apollo', 'Commercial')
    , ('Appleton1', 'Commercial')
    , ('Baptist Beaches', 'Sodexo')
    , ('Florida Hospital', 'Commercial')
    , ('FROST', 'VA/DoD')
    , ('FVAMC1', 'VA/DoD')
    , ('GERMN8R', 'Commercial')
    , ('Glady', 'Commercial')
    , ('Sheldon', 'Sodexo')

DECLARE 
      @Counter INT = 10000
    , @Multiplier INT
    , @CurrentLDN VARCHAR(16)
    , @CurrentEvents INT
    , @CurrentEVS VARCHAR(16)
    , @CurrentStartDate DATETIME2
    , @MinEvents INT = 0
    , @MaxEvents INT = 50
    , @MinDate DATE = '20120101'
    , @MaxDate DATE = '20200707'

WHILE (@Counter > 0)
BEGIN
    SELECT TOP(1)
          @Multiplier = ABS(CHECKSUM(NEWID()) % (@MaxEvents/2 - @MinEvents + 1)) + @MinEvents
        , @CurrentLDN = LDN
        , @CurrentEvents = ABS(CHECKSUM(NEWID()) % (@MaxEvents - @MinEvents + 1)) + @MinEvents
        , @CurrentEVS = EVS
        , @CurrentStartDate = DATEADD(DAY,ABS(CHECKSUM(NEWID())) % (1+DATEDIFF(DAY,@MinDate,@MaxDate)),@MinDate)
    FROM @LDN_EVS_Pairs
    ORDER BY NEWID()

    WHILE(@Multiplier > 0)
    BEGIN
        INSERT INTO [Test](LogicalDeviceName, Events, EVS, StartDate)
        VALUES(@CurrentLDN, @CurrentEvents, @CurrentEVS, @CurrentStartDate)

        SET @Multiplier -= 1
    END
    SET @Counter -= 1
END

这篇文章对生成随机值提供了一些帮助。

相关问题