Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Случайная выборка из может быть повторяющихся  [new]
Dilo Danielidis
Member

Откуда:
Сообщений: 9
Есть таблица tbl(id, snum).
snum может повторяться.

Как сделать в запросе “Select TOP 5 id, snum from tbl order by NewID()” так, чтобы в выборке не встречались более n одинаковых snum

1. Можно удалить заранее такие записи и оставить не более n одинаковых записей в таблице, но этого не хотелось бы. В этом случае вероятность попадания такой записи в конечный select уменьшится, а хотелось бы чем больше повторяющихся записей тем больше вероятность их попадания в конечный select, но не более n.
2. Если сначала выбрать, а потом удалить, тоже не очень хорошо, тогда недостающие записи придется добавить.

Спасибо
28 сен 04, 14:53    [993283]     Ответить | Цитировать Сообщить модератору
 Re: Случайная выборка из может быть повторяющихся  [new]
www.fun4me.narod.ru
Member

Откуда: Moscow
Сообщений: 2406
А проще всего как нибудь так:
create table #tmp(id int, snum int, filed int)
create table #filed(snum int)
declare @q int
declare @n int
declare @t int
declare @c int
select @q=0, @n=2, @t=5

while @q=0
begin
    insert into #tmp(id, snum)
    select TOP 1 id, snum from tbl order by NewID() 
    where snum not in (select snum from #filed)
    if @@rowcount=0
      select @q=1

   select @c=count(*) from #tmp

   if @c=@t 
      select @q=1

   insert into #filed(snum)
   select snum from #tmp
   group by snum
   having (count(*) = @n)

end

select * from #tmp
и не мучаться.
28 сен 04, 15:33    [993523]     Ответить | Цитировать Сообщить модератору
 Re: Случайная выборка из может быть повторяющихся  [new]
Dilo Danielidis
Member

Откуда:
Сообщений: 9
Большое спасибо .
Вот работающий вариант.
Что плохо, добавлять надо по одному, и если записей очень много и выбрать надо тоже много то думаю надо искать другое решение.


CREATE PROCEDURE [dbo].[getData]
@cnt int,
@limit int
AS
--select @cnt=5, @limit=2

create table #tmp(id int, snum varchar(50))
create table #field(snum varchar(50), quantity int)

declare @t int, @sn varchar(50)

while @cnt > 0
begin
select TOP 1 @t=c.id, @sn=c.snum from test1 c
where
c.id not in (select id from #tmp) and
c.snum not in (select snum from #field where quantity >@limit-1)
order by NewID()

if @@rowcount=0 break

insert into #tmp(id, snum) values(@t,@sn)

if not exists(select snum from #field where snum=@sn)
insert into #field (snum,quantity) values(@sn,0)
update #field set quantity=quantity+1 where snum=@sn

set @cnt=@cnt -1

end

select * from #tmp
GO
28 сен 04, 18:48    [994303]     Ответить | Цитировать Сообщить модератору
 Re: Случайная выборка из может быть повторяющихся  [new]
Glory
Member

Откуда:
Сообщений: 104760
а хотелось бы чем больше повторяющихся записей тем больше вероятность их попадания в конечный select, но не более n.
Ну так надо посчитать количество повторяющихся значений - это будет весом записи. И отбирать случайные с учетом веса.
28 сен 04, 19:19    [994359]     Ответить | Цитировать Сообщить модератору
 Re: Случайная выборка из может быть повторяющихся  [new]
Dilo Danielidis
Member

Откуда:
Сообщений: 9
Спасибо, вот


create table #tmp(id int, snum varchar(50))
insert into #tmp (id, snum) select id,snum from tbl order by NewId()

delete #tmp
from #tmp t
inner join (select c.snum from #tmp c group by c.snum having count(c.snum) > 2) p on p.snum = t.snum
where t.id not in (select top 2 tt.id from #tmp tt where tt.snum = t.snum order by t.snum)

select TOP 5 from #tmp


Осталось только параметризировать двойку ( rowcount здесь нельзя устанавливать, а exec не хотелось бы :)
30 сен 04, 13:03    [999579]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить