【问题标题】:MS SQL Calculate MODE on GROUPED dataMS SQL 计算 GROUPED 数据的模式
【发布时间】:2021-11-22 05:35:49
【问题描述】:

我有一个项目表,每个项目都标有纬度和经度以及在表中输入的日期。

每个项目都有一个供应商。

对于每个供应商,我想按 Lat/Lng 对他们的项目进行分组,以了解大多数项目在每个位置的年龄 - 即 MODE。然后,我将在 Google 地图上显示此信息,并使用交通灯标记显示数据的旧/新位置。

我已尝试关注其他 SQL MODE 答案,但它们没有按任何列分组,只是获取一组数据的模式。

这是我的代码:

DECLARE @SupplierID int
SET @SupplierID = 12345

WITH cte AS
(
SELECT 
Round(p.Latitude,2) As Latitude,
Round(p.Longitude,2) As Longitude,
CASE 
WHEN p.Date >= getdate()-30 THEN 1 
WHEN p.Date >= getdate()-60 AND p.Date < getdate()-30 THEN 2 
WHEN p.Date >= getdate()-90 AND Date < getdate()-60 THEN 3 
WHEN p.Date < getdate()-90 THEN 4 END As Age,
Count(*) As Counter
FROM Items p

WHERE
p.SupplierID = @SupplierID AND
p.Latitude is not null AND
p.Longitude is not null

GROUP BY Round(p.Latitude,2),Round(p.Longitude,2),CASE 
WHEN p.Date >= getdate()-30 THEN 1 
WHEN p.Date >= getdate()-60 AND p.Date < getdate()-30 THEN 2 
WHEN p.Date >= getdate()-90 AND Date < getdate()-60 THEN 3 
WHEN p.Date < getdate()-90 THEN 4 END
)

SELECT * FROM cte

这让我得到这样的数据:

Lat    Lng    Age    Counter
12.34  56.78  1      5
12.34  56.78  3      2
12.34  56.78  4      24

23.45  67.89  1      21
23.45  67.89  2      16
23.45  67.89  3      13

现在我需要按每个 Lat/Lng 选择哪个年龄是最流行的分组。尽管摆弄了几个小时,但我似乎无法弄清楚。

我期望的数据是:

Lat    Lng    Mode_Age
12.34  56.78  4
23.45  67.89  1

(我正在四舍五入 Lat/Lng 以减少数据点。)

【问题讨论】:

    标签: sql-server math mean calculated-columns median


    【解决方案1】:

    您可以使用ROW_NUMBER 获取每个分组的顶部项目

    DECLARE @SupplierID int = 12345;
    
    WITH cte AS
    (
        SELECT 
          Round(p.Latitude, 2) As Latitude,
          Round(p.Longitude, 2) As Longitude,
          v.Age,
          Count(*) As Counter,
          ROW_NUMBER() OVER (
            PARTITION BY Round(p.Latitude, 2),
                         Round(p.Longitude, 2)
            ORDER BY COUNT(*) DESC) As Rn
        FROM Items p
        CROSS APPLY (VALUES (
          CASE 
          WHEN p.Date >= getdate()-30 THEN 1 
          WHEN p.Date >= getdate()-60 AND p.Date < getdate()-30 THEN 2 
          WHEN p.Date >= getdate()-90 AND Date < getdate()-60 THEN 3 
          ELSE 4 END
        ) ) As v(Age)
    
        WHERE
          p.SupplierID = @SupplierID AND
          p.Latitude is not null AND
          p.Longitude is not null
    
        GROUP BY
          Round(p.Latitude, 2),
          Round(p.Longitude, 2),
          v.Age
    )
    
    SELECT
      Latitude,
      Longitude,
      Age
    FROM cte
    WHERE Rn = 1;
    

    注意使用CROSS APPLY (VALUES去除重复代码

    【讨论】:

    • 谢谢,但这似乎不起作用。每个纬度/经度都有多个结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    相关资源
    最近更新 更多