Oracle - 如何显示 Min/Max 率的 [公寓] 总数(嵌套聚合函数问题)
Oracle - How to Show Total Number of [Apartments] with Min/Max Rate (Nested Aggregate Functions Issue)
我想探索 simplest/least 性能密集型方法,以在一行数据中显示组中有多少记录与正在分组的数据中的 Min/Max 比率匹配。在我的示例中,建筑物被分组。
在我提供的伪代码中,除了现有的列之外,我还想提供另外两列,以显示每栋建筑内有多少公寓的房价与每栋建筑内的 min/max 房价相匹配。凭直觉,我认为我需要做的就是计算每一次公寓价格与该组的 Min/Max 价格相匹配的情况。这里的问题是我现在正在嵌套聚合函数,但没有成功。也许我遗漏了一些简单的东西。
在这个版本的查询中(伪代码比我的实际代码简单得多)我可以只包装查询,然后使用 Min/Max 值与外部查询中的街道费率进行比较,但我如果我能够在 CASE 和 SUM() 中嵌套 MIN(rate),我正在寻找一种可能与我的伪代码一样简单的方法。除了让这个查询变得复杂之外,我不确定有什么简单的方法。
具体行不通的是LINE 20: SUM(CASE WHEN rate = MIN(rate) THEN 1 ELSE 0 END) AS tot_min_rates
。我把它注释掉了。
WITH rates AS
(
SELECT 1001 AS apt_Key, 5 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1002 AS apt_Key, 4 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1003 AS apt_Key, 17 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1004 AS apt_Key, 10 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1005 AS apt_Key, 4 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1006 AS apt_Key, 7 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1007 AS apt_Key, 5 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1008 AS apt_Key, 13 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1009 AS apt_Key, 10 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1010 AS apt_Key, 13 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1011 AS apt_Key, 8 AS rate, 130 AS building FROM dual
) /* END rates CTE */
SELECT COUNT(apt_key) AS tot_apts, building
, ROUND(AVG(rate),1) AS avg_rate
, MIN(rate) AS min_rate
, MAX(rate) AS max_rate
-- SUM(CASE WHEN rate = MIN(rate) THEN 1 ELSE 0 END) AS tot_min_rates
FROM rates
GROUP BY building
;
据我所知,似乎没有办法在不使用子选择或虚拟表或 CTE 的情况下使它在同一个简单查询中工作。 SQL 无法识别 rate = MAX(rate) 的尝试。据我所知,当您尝试执行此操作时,没有任何数据库引擎可以很好地发挥作用。无赖。
我发现下面的 link 是针对 MS ACCESS 的,但它是同一个问题。
虽然上述 link 中的解决方案有效,但我更喜欢易于阅读和重用的通用 Table 表达式 (CTE) 来组织我的查询,我正在使用的解决方案如下。
WITH rates AS
(
SELECT 1001 AS apt_Key, 5 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1002 AS apt_Key, 4 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1003 AS apt_Key, 17 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1004 AS apt_Key, 10 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1005 AS apt_Key, 4 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1006 AS apt_Key, 7 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1007 AS apt_Key, 5 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1008 AS apt_Key, 13 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1009 AS apt_Key, 10 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1010 AS apt_Key, 13 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1011 AS apt_Key, 8 AS rate, 130 AS building FROM dual
) /* END rates CTE */
/* Use the below to extract the min/max values per Group aka Building in this case */
, building_min_max AS
(
SELECT building, MIN(rate) AS min_rate, MAX(rate) AS max_rate, ROUND(AVG(rate), 1) AS avg_rate
FROM rates
GROUP BY building
)
/* Using a Detailed view mark each max and min rate so we can sum the up later */
SELECT COUNT(apt_key) AS tot_apts, r.building
, ROUND(AVG(rate), 1) AS avg_rate
, MIN(rate) AS min_rate
, MAX(rate) AS max_rate
, SUM(CASE WHEN r.rate = mm.min_rate THEN 1 ELSE 0 END) AS tot_min_rates
, SUM(CASE WHEN r.rate = mm.max_rate THEN 1 ELSE 0 END) AS tot_max_rates
FROM rates r
JOIN building_min_max mm ON mm.building = r.building
GROUP BY r.building
;
我想探索 simplest/least 性能密集型方法,以在一行数据中显示组中有多少记录与正在分组的数据中的 Min/Max 比率匹配。在我的示例中,建筑物被分组。
在我提供的伪代码中,除了现有的列之外,我还想提供另外两列,以显示每栋建筑内有多少公寓的房价与每栋建筑内的 min/max 房价相匹配。凭直觉,我认为我需要做的就是计算每一次公寓价格与该组的 Min/Max 价格相匹配的情况。这里的问题是我现在正在嵌套聚合函数,但没有成功。也许我遗漏了一些简单的东西。
在这个版本的查询中(伪代码比我的实际代码简单得多)我可以只包装查询,然后使用 Min/Max 值与外部查询中的街道费率进行比较,但我如果我能够在 CASE 和 SUM() 中嵌套 MIN(rate),我正在寻找一种可能与我的伪代码一样简单的方法。除了让这个查询变得复杂之外,我不确定有什么简单的方法。
具体行不通的是LINE 20: SUM(CASE WHEN rate = MIN(rate) THEN 1 ELSE 0 END) AS tot_min_rates
。我把它注释掉了。
WITH rates AS
(
SELECT 1001 AS apt_Key, 5 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1002 AS apt_Key, 4 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1003 AS apt_Key, 17 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1004 AS apt_Key, 10 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1005 AS apt_Key, 4 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1006 AS apt_Key, 7 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1007 AS apt_Key, 5 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1008 AS apt_Key, 13 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1009 AS apt_Key, 10 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1010 AS apt_Key, 13 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1011 AS apt_Key, 8 AS rate, 130 AS building FROM dual
) /* END rates CTE */
SELECT COUNT(apt_key) AS tot_apts, building
, ROUND(AVG(rate),1) AS avg_rate
, MIN(rate) AS min_rate
, MAX(rate) AS max_rate
-- SUM(CASE WHEN rate = MIN(rate) THEN 1 ELSE 0 END) AS tot_min_rates
FROM rates
GROUP BY building
;
据我所知,似乎没有办法在不使用子选择或虚拟表或 CTE 的情况下使它在同一个简单查询中工作。 SQL 无法识别 rate = MAX(rate) 的尝试。据我所知,当您尝试执行此操作时,没有任何数据库引擎可以很好地发挥作用。无赖。
我发现下面的 link 是针对 MS ACCESS 的,但它是同一个问题。
虽然上述 link 中的解决方案有效,但我更喜欢易于阅读和重用的通用 Table 表达式 (CTE) 来组织我的查询,我正在使用的解决方案如下。
WITH rates AS
(
SELECT 1001 AS apt_Key, 5 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1002 AS apt_Key, 4 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1003 AS apt_Key, 17 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1004 AS apt_Key, 10 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1005 AS apt_Key, 4 AS rate, 120 AS building FROM dual UNION ALL
SELECT 1006 AS apt_Key, 7 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1007 AS apt_Key, 5 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1008 AS apt_Key, 13 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1009 AS apt_Key, 10 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1010 AS apt_Key, 13 AS rate, 130 AS building FROM dual UNION ALL
SELECT 1011 AS apt_Key, 8 AS rate, 130 AS building FROM dual
) /* END rates CTE */
/* Use the below to extract the min/max values per Group aka Building in this case */
, building_min_max AS
(
SELECT building, MIN(rate) AS min_rate, MAX(rate) AS max_rate, ROUND(AVG(rate), 1) AS avg_rate
FROM rates
GROUP BY building
)
/* Using a Detailed view mark each max and min rate so we can sum the up later */
SELECT COUNT(apt_key) AS tot_apts, r.building
, ROUND(AVG(rate), 1) AS avg_rate
, MIN(rate) AS min_rate
, MAX(rate) AS max_rate
, SUM(CASE WHEN r.rate = mm.min_rate THEN 1 ELSE 0 END) AS tot_min_rates
, SUM(CASE WHEN r.rate = mm.max_rate THEN 1 ELSE 0 END) AS tot_max_rates
FROM rates r
JOIN building_min_max mm ON mm.building = r.building
GROUP BY r.building
;