Sql server 计算另一列(价格)不同范围的中位数(货架天数)

Sql server 计算另一列(价格)不同范围的中位数(货架天数),sql-server,Sql Server,我试图找出一年中每天黄金的中位数。我需要根据不同列中黄金的价格范围将其分开 数据: Create table Daily_Gold_Rate ( S_No int, Dt datetime, Carat int, Gold_Rate numeric(18,2)) Insert into Daily_Gold_Rate values(1,'2013-01-03',18,155.00) Insert into Daily_Gold_Rate values(2,'2013-01-03',22,190

我试图找出一年中每天黄金的中位数。我需要根据不同列中黄金的价格范围将其分开

数据:

Create table Daily_Gold_Rate
( S_No int, Dt datetime, Carat int, Gold_Rate numeric(18,2))

Insert into Daily_Gold_Rate values(1,'2013-01-03',18,155.00)
Insert into Daily_Gold_Rate values(2,'2013-01-03',22,190.50)
Insert into Daily_Gold_Rate values(3,'2013-01-03',24,202.23)
Insert into Daily_Gold_Rate values(4,'2013-01-03',18,400.00)
Insert into Daily_Gold_Rate values(5,'2013-01-03',22,480.50)
Insert into Daily_Gold_Rate values(6,'2013-01-03',24,671.23)

Insert into Daily_Gold_Rate values(7,'2013-01-04',18,153.00)
Insert into Daily_Gold_Rate values(8,'2013-01-04',22,191.00)
Insert into Daily_Gold_Rate values(9,'2013-01-04',24,202.25)
Insert into Daily_Gold_Rate values(10,'2013-01-04',18,351.00)
Insert into Daily_Gold_Rate values(11,'2013-01-04',22,892.00)
Insert into Daily_Gold_Rate values(12,'2013-01-04',24,1003.25)

Insert into Daily_Gold_Rate values(13,'2013-01-05',18,150.00)
Insert into Daily_Gold_Rate values(14,'2013-01-05',22,190.00)
Insert into Daily_Gold_Rate values(15,'2013-01-05',24,203.25)
Insert into Daily_Gold_Rate values(16,'2013-01-05',18,773.00)
Insert into Daily_Gold_Rate values(17,'2013-01-05',22,542.00)
Insert into Daily_Gold_Rate values(18,'2013-01-05',24,182.25)

Insert into Daily_Gold_Rate values(19,'2013-01-06',18,158.00)
Insert into Daily_Gold_Rate values(20,'2013-01-06',22,189.50)
Insert into Daily_Gold_Rate values(21,'2013-01-06',24,201.50)
Insert into Daily_Gold_Rate values(22,'2013-01-06',18,624.00)
Insert into Daily_Gold_Rate values(23,'2013-01-06',
Insert into Daily_Gold_Rate values(24,'2013-01-06',24,411.50)
简单百分位控制如下所示:

Select Dt, Carat, Gold_Rate, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY 
Carat) OVER (PARTITION BY Carat) AS MedianCont
from Daily_Gold_Rate
order by Dt;Expected output is like this:
返回以下数据:

Dt            | Carat | Gold_Rate | MedianCont
2013-01-03 00:00:00.000 | 18 | 155.00 | 18
2013-01-03 00:00:00.000 | 18 | 400.00 | 18
2013-01-03 00:00:00.000 | 22 | 480.50 | 22
2013-01-03 00:00:00.000 | 22 | 190.50 | 22
2013-01-03 00:00:00.000 | 24 | 202.23 | 24
2013-01-03 00:00:00.000 | 24 | 671.23 | 24
2013-01-04 00:00:00.000 | 24 | 202.25 | 24
2013-01-04 00:00:00.000 | 24 | 1003.25 | 24
2013-01-04 00:00:00.000 | 18 | 153.00 | 18
2013-01-04 00:00:00.000 | 18 | 351.00 | 18
2013-01-04 00:00:00.000 | 22 | 892.00 | 22
2013-01-04 00:00:00.000 | 22 | 191.00 | 22
2013-01-05 00:00:00.000 | 22 | 542.00 | 22
2013-01-05 00:00:00.000 | 22 | 190.00 | 22
2013-01-05 00:00:00.000 | 18 | 150.00 | 18
2013-01-05 00:00:00.000 | 18 | 773.00 | 18
2013-01-05 00:00:00.000 | 24 | 203.25 | 24
2013-01-05 00:00:00.000 | 24 | 182.25 | 24
2013-01-06 00:00:00.000 | 24 | 201.50 | 24
2013-01-06 00:00:00.000 | 24 | 411.50 | 24
2013-01-06 00:00:00.000 | 18 | 158.00 | 18
2013-01-06 00:00:00.000 | 18 | 624.00 | 18
2013-01-06 00:00:00.000 | 22 | 735.50 | 22
2013-01-06 00:00:00.000 | 22 | 189.50 | 22
我需要关注黄金价格区间。因此,我尝试通过以下查询:

with a as (
    select year(Dt) as "year", month(Dt) as "month", day(Dt) as "day",
    case when Gold_Rate / 200 < 5 then Gold_Rate / 200 else 5 end as 
price_bucket,
    PERCENTILE_CONT(.50) WITHIN GROUP (ORDER BY Carat) over (PARTITION BY 
day(Dt), month(Dt)) as MED_days
from Daily_Gold_Rate
group by year(Dt), month(Dt), day(Dt), Gold_Rate / 200, Carat)
select "year", "month", "day",
[1] as "less than 400", [2] as "400-599", [3] as "600-799", [4] as "800-
999", [5] as "Over 1000"
from a pivot (max(MED_days) for price_bucket in ([1], [2], [3], [4], [5])) p
order by "year", "month", "day";

百分比计算前的旋转:

小提琴

以下是按克拉或费率计算的一些工作查询:

订正答复: 按日收费

日均克拉

小提琴

按月:仅供参考


dbfiddle

MCVE我建议你读一下这些:谢谢,你已经用过了。根据您的建议,我相信在描述我的问题时,我缺少了数据创建部分insert,create。为了更好地理解,我改变了我的描述。我希望现在一切正常。这是返回整个价格范围的中位数0-Max。整个时间范围的价格。在percentile_cont函数中采用monthdatetime分割法按月分割中值,但仍适用于每个月的整个价格范围。如何获得单独价格范围的中间值?首先将原始数据导入列中。然后在单独的列上运行窗口函数现在我有机会处理示例数据,相信我有一个有效的查询供您使用。谢谢,@Used\u By\u。我在case语法上犯了一个基本错误。我不知道你在上面的评论中是什么意思,但是如果你先旋转,然后计算百分位数,结果不会有什么不同。我在顶部又添加了一个变量,它首先旋转。鉴于您尚未提供预期结果,我将保持原样。
Year | Month | Day | 1-399 | 400-599 | 600-799| 800-999| Over 1000
2013 | 1     | 3   | NULL  | 22      | NULL   | NULL   | NULL
2013 | 1     | 4   | NULL  | NULL    | NULL   | NULL   | 22
2013 | 1     | 5   | NULL  | NULL    | NULL   | NULL   | NULL
2013 | 1     | 6   | NULL  | NULL    | NULL   | NULL   | NULL
select distinct
      dt
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ratelt400)      OVER (PARTITION BY dt) ratelt400
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ratebtwn400599) OVER (PARTITION BY dt) ratebtwn400599
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ratebtwn600799) OVER (PARTITION BY dt) ratebtwn600799
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ratebtwn800999) OVER (PARTITION BY dt) ratebtwn800999
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY rateovr1000)    OVER (PARTITION BY dt) rateovr1000
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY caratlt400)      OVER (PARTITION BY dt) caratlt400
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY caratbtwn400599) OVER (PARTITION BY dt) caratbtwn400599
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY caratbtwn600799) OVER (PARTITION BY dt) caratbtwn600799
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY caratbtwn800999) OVER (PARTITION BY dt) caratbtwn800999
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY caratovr1000)    OVER (PARTITION BY dt) caratovr1000
from (
SELECT
      DATEADD(day, DATEDIFF(day, 0, dt), 0) dt
    , CASE WHEN Gold_Rate < 400               THEN Gold_Rate END ratelt400
    , CASE WHEN Gold_Rate BETWEEN 400 AND 599 THEN Gold_Rate END ratebtwn400599
    , CASE WHEN Gold_Rate BETWEEN 600 AND 799 THEN Gold_Rate END ratebtwn600799
    , CASE WHEN Gold_Rate BETWEEN 800 AND 999 THEN Gold_Rate END ratebtwn800999
    , CASE WHEN Gold_Rate >= 1000             THEN Gold_Rate END rateovr1000
    , CASE WHEN Gold_Rate < 400               THEN carat END caratlt400
    , CASE WHEN Gold_Rate BETWEEN 400 AND 599 THEN carat END caratbtwn400599
    , CASE WHEN Gold_Rate BETWEEN 600 AND 799 THEN carat END caratbtwn600799
    , CASE WHEN Gold_Rate BETWEEN 800 AND 999 THEN carat END caratbtwn800999
    , CASE WHEN Gold_Rate >= 1000             THEN carat END caratovr1000
FROM Daily_Gold_Rate
) d
GO
dt | ratelt400 | ratebtwn400599 | ratebtwn600799 | ratebtwn800999 | rateovr1000 | caratlt400 | caratbtwn400599 | caratbtwn600799 | caratbtwn800999 | caratovr1000 :------------------ | --------: | -------------: | -------------: | -------------: | ----------: | ---------: | --------------: | --------------: | --------------: | -----------: 03/01/2013 00:00:00 | 190.5 | 440.25 | 671.23 | null | null | 22 | 20 | 24 | null | null 04/01/2013 00:00:00 | 196.625 | null | null | 892 | 1003.25 | 20 | null | null | 22 | 24 05/01/2013 00:00:00 | 186.125 | 542 | 773 | null | null | 23 | 22 | 18 | null | null 06/01/2013 00:00:00 | 189.5 | 411.5 | 624 | null | null | 22 | 24 | 18 | null | null
SELECT DISTINCT
      DATEADD(day, DATEDIFF(day, 0, dt), 0) dt
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate < 400               THEN Gold_Rate END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) lt400
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 400 AND 599 THEN Gold_Rate END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) btwn400599
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 600 AND 799 THEN Gold_Rate END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) btwn600799
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 800 AND 999 THEN Gold_Rate END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) btwn800999
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate >= 1000             THEN Gold_Rate END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) ovr1000
FROM Daily_Gold_Rate

GO
dt | lt400 | btwn400599 | btwn600799 | btwn800999 | ovr1000 :------------------ | ------: | ---------: | ---------: | ---------: | ------: 03/01/2013 00:00:00 | 190.5 | 440.25 | 671.23 | null | null 04/01/2013 00:00:00 | 196.625 | null | null | 892 | 1003.25 05/01/2013 00:00:00 | 186.125 | 542 | 773 | null | null 06/01/2013 00:00:00 | 189.5 | 411.5 | 624 | null | null
SELECT DISTINCT
      DATEADD(day, DATEDIFF(day, 0, dt), 0) dt
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate < 400               THEN carat END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) lt400
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 400 AND 599 THEN carat END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) btwn400599
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 600 AND 799 THEN carat END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) btwn600799
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 800 AND 999 THEN carat END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) btwn800999
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate >= 1000             THEN carat END) OVER (PARTITION BY DATEADD(day, DATEDIFF(day, 0, dt), 0)) ovr1000
FROM Daily_Gold_Rate
GO
dt | lt400 | btwn400599 | btwn600799 | btwn800999 | ovr1000 :------------------ | ----: | ---------: | ---------: | ---------: | ------: 03/01/2013 00:00:00 | 22 | 20 | 24 | null | null 04/01/2013 00:00:00 | 20 | null | null | 22 | 24 05/01/2013 00:00:00 | 23 | 22 | 18 | null | null 06/01/2013 00:00:00 | 22 | 24 | 18 | null | null
SELECT DISTINCT
      DATEADD(MONTH, DATEDIFF(MONTH, 0, dt), 0) dt
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate < 400               THEN Gold_Rate END) OVER (PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, dt), 0)) lt400
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 400 AND 599 THEN Gold_Rate END) OVER (PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, dt), 0)) btwn400599
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 600 AND 799 THEN Gold_Rate END) OVER (PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, dt), 0)) btwn600799
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate BETWEEN 800 AND 999 THEN Gold_Rate END) OVER (PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, dt), 0)) btwn800999
    , PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN Gold_Rate >= 1000             THEN Gold_Rate END) OVER (PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, dt), 0)) ovr1000
FROM Daily_Gold_Rate

GO
dt | lt400 | btwn400599 | btwn600799 | btwn800999 | ovr1000 :------------------ | -----: | ---------: | ---------: | ---------: | ------: 01/01/2013 00:00:00 | 190.25 | 446 | 671.23 | 892 | 1003.25