根据不同的值从列中选择随机值

selecting random value from column based on distinct values

我在 table 中有以下数据:-

| item    | rate |
-------------------
| a       | 50   |
| a       | 12   |
| a       | 26   |
| b       | 12   |
| b       | 15   |
| b       | 45   |
| b       | 10   |
| c       | 5    |
| c       | 15   |

我需要一个查询 return 以下输出:

| item no | rate |
------------------
| a       | 12 |  --from (26 , 12 , 50)
| b       | 45 | --from (12 ,15 , 45 , 10)
| c       | 5  | --from (5 , 15)

即 item_no 应该是不同的并且随机具有一个速率值..

提前致谢

一种方法是使用行号window函数,item作为分区。然后在每个分区内使用 ORDER BY NEWID() 生成随机排序,任意保留每个 item 分区的第一行。

SELECT t.item,
       t.rate
FROM
(
    SELECT item,
           rate,
           ROW_NUMBER() OVER(PARTITION BY item ORDER BY NEWID()) AS rn
    FROM yourTable
) t
WHERE t.rn = 1
WITH
CTE
AS
(
    SELECT DISTINCT
        item
    FROM T
)
SELECT
    CTE.item
    ,A.rate
FROM
    CTE
    CROSS APPLY
    (
        SELECT TOP(1) 
            T.rate
        FROM T
        WHERE T.item = CTE.item
        ORDER BY CRYPT_GEN_RANDOM(4)
    ) AS A
;

(item) include (rate) 上的索引会有所帮助。

HERE NEWID()用于分区生成随机排序,
在 partition 中,它将保留每个项目的第一行。

with cte as
    (

        SELECT item,
               rate,
               ROW_NUMBER() OVER(PARTITION BY item ORDER BY NEWID()) AS rn
        FROM #Table1
        )
        select item,rate from cte where rn=1
; WITH tb( item, rate)AS(
    SELECT 'a',50 UNION
    SELECT 'a',12  UNION
    SELECT 'a', 26 UNION
    SELECT 'b',12  UNION
    SELECT 'b', 15 UNION
    SELECT 'b',10 UNION
    SELECT 'c',5  UNION
    SELECT 'c',15 
    ) 
    SELECT * FROM (
        SELECT *,ROW_NUMBER()OVER( PARTITION BY item ORDER BY NEWID())  AS rn FROM tb
    ) t WHERE t.rn=1

尝试一次这个查询。

select * into #temp  from (
        SELECT 'a' item,50 rate 
        UNION ALL
        SELECT 'a',12  
        UNION ALL
        SELECT 'a', 26 
        UNION ALL
        SELECT 'b',12  
        UNION ALL
        SELECT 'b', 15 
        UNION ALL
        SELECT 'b',10 
        UNION ALL
        SELECT 'c',5  
        UNION ALL
        SELECT 'c',15 )as a

    select * from (
    select *,row_number()over(partition by item  ORDER BY newid() )as runm from #temp
    ) as a
    where runm=1

注意:上面的查询给出了每次新的输出,因为 newid() 为每次执行生成一个新的 id。