MS SQL 计算 GROUPED 数据的模式
MS SQL Calculate MODE on GROUPED data
我有 table 个项目,每个项目都标有纬度和经度以及输入 table 的日期。
每个项目都有一个供应商。
对于每个供应商,我想按 Lat/Lng 对他们的项目进行分组,以找出每个位置的大多数项目的年龄 - 即模式。然后,我将在 Google 地图上显示此内容,并用红绿灯标记显示数据所在的位置 old/new。
我试过遵循其他 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
现在我需要 select 每个 Lat/Lng 哪个年龄组最普遍。尽管摆弄了几个小时,我似乎还是想不通。
我期望的数据是:
Lat Lng Mode_Age
12.34 56.78 4
23.45 67.89 1
(我将 Lat/Lng 四舍五入以减少数据点。)
您可以使用 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;
Note the use of CROSS APPLY (VALUES
to remove the code duplication
我有 table 个项目,每个项目都标有纬度和经度以及输入 table 的日期。
每个项目都有一个供应商。
对于每个供应商,我想按 Lat/Lng 对他们的项目进行分组,以找出每个位置的大多数项目的年龄 - 即模式。然后,我将在 Google 地图上显示此内容,并用红绿灯标记显示数据所在的位置 old/new。
我试过遵循其他 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
现在我需要 select 每个 Lat/Lng 哪个年龄组最普遍。尽管摆弄了几个小时,我似乎还是想不通。
我期望的数据是:
Lat Lng Mode_Age
12.34 56.78 4
23.45 67.89 1
(我将 Lat/Lng 四舍五入以减少数据点。)
您可以使用 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;
Note the use of
CROSS APPLY (VALUES
to remove the code duplication