是否可以通过查询获得组中组内的随机值?
Posted
技术标签:
【中文标题】是否可以通过查询获得组中组内的随机值?【英文标题】:Is it possible to get a random value within a group in a group by query? 【发布时间】:2021-12-30 12:16:15 【问题描述】:我想在分组查询中获得随机值,如下所示:
SELECT city
, SOME_RANDOMIZER_FUNC(latitude) as "RANDOM_LATITUDE_IN_CITY"
, SOME_RANDOMIZER_FUNC(longitude) AS "RANDOM_LONGITUDE_IN_CITY"
FROM some_table
GROUP BY city
输入:
city LATITUDE LONGITUDE
STO -31.3935 -57.9413
STO -31.0274 -57.8081
STO -30.7852 -57.7765
STO -30.4274 -56.4718
NDU -30.2747 -57.6023
NDU -32.2909 -58.0737
NDU -32.0286 -57.8468
NDU -32.3600 -57.2021
NDU -32.6816 -57.6541
MBO -31.7085 -55.9873
MBO -30.9359 -55.5457
MBO -31.1972 -55.7574
MBO -31.7711 -54.6904
想要的输出:
city RANDOM_LATITUDE_IN_CITY RANDOM_LONGITUDE_IN_CITY
STO -31.0274 -57.9413
NDU -32.3600 -57.6541
MBO -30.9359 -55.5457
函数SOME_RANDOMIZER_FUNC
返回组内的随机值。
【问题讨论】:
有一组经纬度属于同一个城市。但是,一个坐标可以属于一个记录,另一个属于另一个记录,我不知道这是不是问题 我猜样本数据(以及所需的输出)会有所帮助。 【参考方案1】:在随机函数的输入参数中,您呈现所有数据,然后对其应用分组,这是不允许的。 最好的方法是使用以下代码:
with s_table as (
select
city,
latitude,
longitude,
row_number() over(partition by city order by DBMS_RANDOM.VALUE) as random_sort
from
some_table
)
select
city,
latitude,
longitude
from
s_table
where
random_sort =1
【讨论】:
与我的解决方案相同,只是我迟到了两分钟 :-) Oracle 中没有RAND()
。请改用DBMS_RANDOM.VALUE
。
是的,每个引擎都有生成随机数的功能。 rand()、random()、DBMS_RANDOM.VALUE 等。感谢您的提示。【参考方案2】:
如果您想要一些不确定的行,那么您可以尝试 any_value
函数,自 21c 以来记录:
create table t as select trunc((level - 1)/10) as city , level as lat , 100 - level as lon from dual connect by level < 101
城市 |纬度 |伦敦 ---: | --: | --: 0 | 1 | 99 1 | 11 | 89 2 | 21 | 79 3 | 31 | 69 4 | 41 | 59 5 | 51 | 49 6 | 61 | 39 7 | 71 | 29 8 | 81 | 19 9 | 91 | 9select /*+gather_plan_statistics*/ city , any_value(lat) as lat , any_value(lon) as lon from t group by city
db小提琴here
【讨论】:
OP 强调他需要一个 random 值。那不是ANY_VALUE()
。非确定性并不意味着随机。我很确定您已经意识到了这一点,但它可能会改善您的答案以澄清这一点。【参考方案3】:
您可以将 FIRST_VALUE 与 DBMS_RANDOM.VALUE 结合使用
例如:
城市 |纬度 |经度 :--- | --------: | --------: 管理层收购 | -30.9359 | -55.5457 国防大学 | -32.6816 | -57.6541 申通 | -30.4274 | -56.4718SELECT city, latitude, longitude FROM ( SELECT city , FIRST_VALUE(latitude) OVER (PARTITION BY city ORDER BY DBMS_RANDOM.VALUE) as latitude , FIRST_VALUE(longitude) OVER (PARTITION BY city ORDER BY DBMS_RANDOM.VALUE) as longitude FROM some_table ) GROUP BY city, latitude, longitude ORDER BY city;
dbfiddle here
上的演示【讨论】:
【参考方案4】:为每个城市随机编号,然后保留编号为 1 的行。
SELECT city, latitude, longitude
FROM
(
SELECT
city, latitude, longitude,
ROW_NUMBER() OVER (PARTITION BY city ORDER BY DBMS_RANDOM.VALUE) AS rn
FROM some_table
)
WHERE rn = 1
ORDER BY city;
【讨论】:
以上是关于是否可以通过查询获得组中组内的随机值?的主要内容,如果未能解决你的问题,请参考以下文章